1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package java.util;
28
29import java.nio.file.Path;
30import java.nio.file.Files;
31import java.util.regex.*;
32import java.io.*;
33import java.math.*;
34import java.nio.*;
35import java.nio.channels.*;
36import java.nio.charset.*;
37import java.text.*;
38import java.util.Locale;
39
40import sun.misc.LRUCache;
41
42/**
43 * A simple text scanner which can parse primitive types and strings using
44 * regular expressions.
45 *
46 * <p>A <code>Scanner</code> breaks its input into tokens using a
47 * delimiter pattern, which by default matches whitespace. The resulting
48 * tokens may then be converted into values of different types using the
49 * various <tt>next</tt> methods.
50 *
51 * <p>For example, this code allows a user to read a number from
52 * <tt>System.in</tt>:
53 * <blockquote><pre>{@code
54 *     Scanner sc = new Scanner(System.in);
55 *     int i = sc.nextInt();
56 * }</pre></blockquote>
57 *
58 * <p>As another example, this code allows <code>long</code> types to be
59 * assigned from entries in a file <code>myNumbers</code>:
60 * <blockquote><pre>{@code
61 *      Scanner sc = new Scanner(new File("myNumbers"));
62 *      while (sc.hasNextLong()) {
63 *          long aLong = sc.nextLong();
64 *      }
65 * }</pre></blockquote>
66 *
67 * <p>The scanner can also use delimiters other than whitespace. This
68 * example reads several items in from a string:
69 * <blockquote><pre>{@code
70 *     String input = "1 fish 2 fish red fish blue fish";
71 *     Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
72 *     System.out.println(s.nextInt());
73 *     System.out.println(s.nextInt());
74 *     System.out.println(s.next());
75 *     System.out.println(s.next());
76 *     s.close();
77 * }</pre></blockquote>
78 * <p>
79 * prints the following output:
80 * <blockquote><pre>{@code
81 *     1
82 *     2
83 *     red
84 *     blue
85 * }</pre></blockquote>
86 *
87 * <p>The same output can be generated with this code, which uses a regular
88 * expression to parse all four tokens at once:
89 * <blockquote><pre>{@code
90 *     String input = "1 fish 2 fish red fish blue fish";
91 *     Scanner s = new Scanner(input);
92 *     s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
93 *     MatchResult result = s.match();
94 *     for (int i=1; i<=result.groupCount(); i++)
95 *         System.out.println(result.group(i));
96 *     s.close();
97 * }</pre></blockquote>
98 *
99 * <p>The <a name="default-delimiter">default whitespace delimiter</a> used
100 * by a scanner is as recognized by {@link java.lang.Character}.{@link
101 * java.lang.Character#isWhitespace(char) isWhitespace}. The {@link #reset}
102 * method will reset the value of the scanner's delimiter to the default
103 * whitespace delimiter regardless of whether it was previously changed.
104 *
105 * <p>A scanning operation may block waiting for input.
106 *
107 * <p>The {@link #next} and {@link #hasNext} methods and their
108 * primitive-type companion methods (such as {@link #nextInt} and
109 * {@link #hasNextInt}) first skip any input that matches the delimiter
110 * pattern, and then attempt to return the next token. Both <tt>hasNext</tt>
111 * and <tt>next</tt> methods may block waiting for further input.  Whether a
112 * <tt>hasNext</tt> method blocks has no connection to whether or not its
113 * associated <tt>next</tt> method will block.
114 *
115 * <p> The {@link #findInLine}, {@link #findWithinHorizon}, and {@link #skip}
116 * methods operate independently of the delimiter pattern. These methods will
117 * attempt to match the specified pattern with no regard to delimiters in the
118 * input and thus can be used in special circumstances where delimiters are
119 * not relevant. These methods may block waiting for more input.
120 *
121 * <p>When a scanner throws an {@link InputMismatchException}, the scanner
122 * will not pass the token that caused the exception, so that it may be
123 * retrieved or skipped via some other method.
124 *
125 * <p>Depending upon the type of delimiting pattern, empty tokens may be
126 * returned. For example, the pattern <tt>"\\s+"</tt> will return no empty
127 * tokens since it matches multiple instances of the delimiter. The delimiting
128 * pattern <tt>"\\s"</tt> could return empty tokens since it only passes one
129 * space at a time.
130 *
131 * <p> A scanner can read text from any object which implements the {@link
132 * java.lang.Readable} interface.  If an invocation of the underlying
133 * readable's {@link java.lang.Readable#read} method throws an {@link
134 * java.io.IOException} then the scanner assumes that the end of the input
135 * has been reached.  The most recent <tt>IOException</tt> thrown by the
136 * underlying readable can be retrieved via the {@link #ioException} method.
137 *
138 * <p>When a <code>Scanner</code> is closed, it will close its input source
139 * if the source implements the {@link java.io.Closeable} interface.
140 *
141 * <p>A <code>Scanner</code> is not safe for multithreaded use without
142 * external synchronization.
143 *
144 * <p>Unless otherwise mentioned, passing a <code>null</code> parameter into
145 * any method of a <code>Scanner</code> will cause a
146 * <code>NullPointerException</code> to be thrown.
147 *
148 * <p>A scanner will default to interpreting numbers as decimal unless a
149 * different radix has been set by using the {@link #useRadix} method. The
150 * {@link #reset} method will reset the value of the scanner's radix to
151 * <code>10</code> regardless of whether it was previously changed.
152 *
153 * <h3> <a name="localized-numbers">Localized numbers</a> </h3>
154 *
155 * <p> An instance of this class is capable of scanning numbers in the standard
156 * formats as well as in the formats of the scanner's locale. A scanner's
157 * <a name="initial-locale">initial locale </a>is the value returned by the {@link
158 * java.util.Locale#getDefault(Locale.Category)
159 * Locale.getDefault(Locale.Category.FORMAT)} method; it may be changed via the {@link
160 * #useLocale} method. The {@link #reset} method will reset the value of the
161 * scanner's locale to the initial locale regardless of whether it was
162 * previously changed.
163 *
164 * <p>The localized formats are defined in terms of the following parameters,
165 * which for a particular locale are taken from that locale's {@link
166 * java.text.DecimalFormat DecimalFormat} object, <tt>df</tt>, and its and
167 * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,
168 * <tt>dfs</tt>.
169 *
170 * <blockquote><dl>
171 *     <dt><i>LocalGroupSeparator&nbsp;&nbsp;</i>
172 *         <dd>The character used to separate thousands groups,
173 *         <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
174 *         java.text.DecimalFormatSymbols#getGroupingSeparator
175 *         getGroupingSeparator()}
176 *     <dt><i>LocalDecimalSeparator&nbsp;&nbsp;</i>
177 *         <dd>The character used for the decimal point,
178 *     <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
179 *     java.text.DecimalFormatSymbols#getDecimalSeparator
180 *     getDecimalSeparator()}
181 *     <dt><i>LocalPositivePrefix&nbsp;&nbsp;</i>
182 *         <dd>The string that appears before a positive number (may
183 *         be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
184 *         java.text.DecimalFormat#getPositivePrefix
185 *         getPositivePrefix()}
186 *     <dt><i>LocalPositiveSuffix&nbsp;&nbsp;</i>
187 *         <dd>The string that appears after a positive number (may be
188 *         empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
189 *         java.text.DecimalFormat#getPositiveSuffix
190 *         getPositiveSuffix()}
191 *     <dt><i>LocalNegativePrefix&nbsp;&nbsp;</i>
192 *         <dd>The string that appears before a negative number (may
193 *         be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
194 *         java.text.DecimalFormat#getNegativePrefix
195 *         getNegativePrefix()}
196 *     <dt><i>LocalNegativeSuffix&nbsp;&nbsp;</i>
197 *         <dd>The string that appears after a negative number (may be
198 *         empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
199 *     java.text.DecimalFormat#getNegativeSuffix
200 *     getNegativeSuffix()}
201 *     <dt><i>LocalNaN&nbsp;&nbsp;</i>
202 *         <dd>The string that represents not-a-number for
203 *         floating-point values,
204 *         <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
205 *         java.text.DecimalFormatSymbols#getNaN
206 *         getNaN()}
207 *     <dt><i>LocalInfinity&nbsp;&nbsp;</i>
208 *         <dd>The string that represents infinity for floating-point
209 *         values, <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
210 *         java.text.DecimalFormatSymbols#getInfinity
211 *         getInfinity()}
212 * </dl></blockquote>
213 *
214 * <h4> <a name="number-syntax">Number syntax</a> </h4>
215 *
216 * <p> The strings that can be parsed as numbers by an instance of this class
217 * are specified in terms of the following regular-expression grammar, where
218 * Rmax is the highest digit in the radix being used (for example, Rmax is 9 in base 10).
219 *
220 * <dl>
221 *   <dt><i>NonAsciiDigit</i>:
222 *       <dd>A non-ASCII character c for which
223 *            {@link java.lang.Character#isDigit Character.isDigit}<tt>(c)</tt>
224 *                        returns&nbsp;true
225 *
226 *   <dt><i>Non0Digit</i>:
227 *       <dd><tt>[1-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i>
228 *
229 *   <dt><i>Digit</i>:
230 *       <dd><tt>[0-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i>
231 *
232 *   <dt><i>GroupedNumeral</i>:
233 *       <dd><tt>(&nbsp;</tt><i>Non0Digit</i>
234 *                   <i>Digit</i><tt>?
235 *                   </tt><i>Digit</i><tt>?</tt>
236 *       <dd>&nbsp;&nbsp;&nbsp;&nbsp;<tt>(&nbsp;</tt><i>LocalGroupSeparator</i>
237 *                         <i>Digit</i>
238 *                         <i>Digit</i>
239 *                         <i>Digit</i><tt> )+ )</tt>
240 *
241 *   <dt><i>Numeral</i>:
242 *       <dd><tt>( ( </tt><i>Digit</i><tt>+ )
243 *               | </tt><i>GroupedNumeral</i><tt> )</tt>
244 *
245 *   <dt><a name="Integer-regex"><i>Integer</i>:</a>
246 *       <dd><tt>( [-+]? ( </tt><i>Numeral</i><tt>
247 *                               ) )</tt>
248 *       <dd><tt>| </tt><i>LocalPositivePrefix</i> <i>Numeral</i>
249 *                      <i>LocalPositiveSuffix</i>
250 *       <dd><tt>| </tt><i>LocalNegativePrefix</i> <i>Numeral</i>
251 *                 <i>LocalNegativeSuffix</i>
252 *
253 *   <dt><i>DecimalNumeral</i>:
254 *       <dd><i>Numeral</i>
255 *       <dd><tt>| </tt><i>Numeral</i>
256 *                 <i>LocalDecimalSeparator</i>
257 *                 <i>Digit</i><tt>*</tt>
258 *       <dd><tt>| </tt><i>LocalDecimalSeparator</i>
259 *                 <i>Digit</i><tt>+</tt>
260 *
261 *   <dt><i>Exponent</i>:
262 *       <dd><tt>( [eE] [+-]? </tt><i>Digit</i><tt>+ )</tt>
263 *
264 *   <dt><a name="Decimal-regex"><i>Decimal</i>:</a>
265 *       <dd><tt>( [-+]? </tt><i>DecimalNumeral</i>
266 *                         <i>Exponent</i><tt>? )</tt>
267 *       <dd><tt>| </tt><i>LocalPositivePrefix</i>
268 *                 <i>DecimalNumeral</i>
269 *                 <i>LocalPositiveSuffix</i>
270 *                 <i>Exponent</i><tt>?</tt>
271 *       <dd><tt>| </tt><i>LocalNegativePrefix</i>
272 *                 <i>DecimalNumeral</i>
273 *                 <i>LocalNegativeSuffix</i>
274 *                 <i>Exponent</i><tt>?</tt>
275 *
276 *   <dt><i>HexFloat</i>:
277 *       <dd><tt>[-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+
278 *                 ([pP][-+]?[0-9]+)?</tt>
279 *
280 *   <dt><i>NonNumber</i>:
281 *       <dd><tt>NaN
282 *                          | </tt><i>LocalNan</i><tt>
283 *                          | Infinity
284 *                          | </tt><i>LocalInfinity</i>
285 *
286 *   <dt><i>SignedNonNumber</i>:
287 *       <dd><tt>( [-+]? </tt><i>NonNumber</i><tt> )</tt>
288 *       <dd><tt>| </tt><i>LocalPositivePrefix</i>
289 *                 <i>NonNumber</i>
290 *                 <i>LocalPositiveSuffix</i>
291 *       <dd><tt>| </tt><i>LocalNegativePrefix</i>
292 *                 <i>NonNumber</i>
293 *                 <i>LocalNegativeSuffix</i>
294 *
295 *   <dt><a name="Float-regex"><i>Float</i></a>:
296 *       <dd><i>Decimal</i>
297 *           <tt>| </tt><i>HexFloat</i>
298 *           <tt>| </tt><i>SignedNonNumber</i>
299 *
300 * </dl>
301 * <p>Whitespace is not significant in the above regular expressions.
302 *
303 * @since   1.5
304 */
305public final class Scanner implements Iterator<String>, Closeable {
306
307    // Internal buffer used to hold input
308    private CharBuffer buf;
309
310    // Size of internal character buffer
311    private static final int BUFFER_SIZE = 1024; // change to 1024;
312
313    // The index into the buffer currently held by the Scanner
314    private int position;
315
316    // Internal matcher used for finding delimiters
317    private Matcher matcher;
318
319    // Pattern used to delimit tokens
320    private Pattern delimPattern;
321
322    // Pattern found in last hasNext operation
323    private Pattern hasNextPattern;
324
325    // Position after last hasNext operation
326    private int hasNextPosition;
327
328    // Result after last hasNext operation
329    private String hasNextResult;
330
331    // The input source
332    private Readable source;
333
334    // Boolean is true if source is done
335    private boolean sourceClosed = false;
336
337    // Boolean indicating more input is required
338    private boolean needInput = false;
339
340    // Boolean indicating if a delim has been skipped this operation
341    private boolean skipped = false;
342
343    // A store of a position that the scanner may fall back to
344    private int savedScannerPosition = -1;
345
346    // A cache of the last primitive type scanned
347    private Object typeCache = null;
348
349    // Boolean indicating if a match result is available
350    private boolean matchValid = false;
351
352    // Boolean indicating if this scanner has been closed
353    private boolean closed = false;
354
355    // The current radix used by this scanner
356    private int radix = 10;
357
358    // The default radix for this scanner
359    private int defaultRadix = 10;
360
361    // The locale used by this scanner
362    private Locale locale = null;
363
364    // A cache of the last few recently used Patterns
365    private LRUCache<String,Pattern> patternCache =
366    new LRUCache<String,Pattern>(7) {
367        protected Pattern create(String s) {
368            return Pattern.compile(s);
369        }
370        protected boolean hasName(Pattern p, String s) {
371            return p.pattern().equals(s);
372        }
373    };
374
375    // A holder of the last IOException encountered
376    private IOException lastException;
377
378    // A pattern for java whitespace
379    private static Pattern WHITESPACE_PATTERN = Pattern.compile(
380                                                "\\p{javaWhitespace}+");
381
382    // A pattern for any token
383    private static Pattern FIND_ANY_PATTERN = Pattern.compile("(?s).*");
384
385    // A pattern for non-ASCII digits
386    private static Pattern NON_ASCII_DIGIT = Pattern.compile(
387        "[\\p{javaDigit}&&[^0-9]]");
388
389    // Fields and methods to support scanning primitive types
390
391    /**
392     * Locale dependent values used to scan numbers
393     */
394    private String groupSeparator = "\\,";
395    private String decimalSeparator = "\\.";
396    private String nanString = "NaN";
397    private String infinityString = "Infinity";
398    private String positivePrefix = "";
399    private String negativePrefix = "\\-";
400    private String positiveSuffix = "";
401    private String negativeSuffix = "";
402
403    /**
404     * Fields and an accessor method to match booleans
405     */
406    private static volatile Pattern boolPattern;
407    private static final String BOOLEAN_PATTERN = "true|false";
408    private static Pattern boolPattern() {
409        Pattern bp = boolPattern;
410        if (bp == null)
411            boolPattern = bp = Pattern.compile(BOOLEAN_PATTERN,
412                                          Pattern.CASE_INSENSITIVE);
413        return bp;
414    }
415
416    /**
417     * Fields and methods to match bytes, shorts, ints, and longs
418     */
419    private Pattern integerPattern;
420    private String digits = "0123456789abcdefghijklmnopqrstuvwxyz";
421    private String non0Digit = "[\\p{javaDigit}&&[^0]]";
422    private int SIMPLE_GROUP_INDEX = 5;
423    private String buildIntegerPatternString() {
424        String radixDigits = digits.substring(0, radix);
425        // Android-changed: Support non-decimal starting digits. (i.e, a-z are valid radix digits).
426        String nonZeroRadixDigits = "((?i)[" + digits.substring(1, radix) + "]|(" + non0Digit + "))";
427
428        // \\p{javaDigit} is not guaranteed to be appropriate
429        // here but what can we do? The final authority will be
430        // whatever parse method is invoked, so ultimately the
431        // Scanner will do the right thing
432        String digit = "((?i)["+radixDigits+"]|\\p{javaDigit})";
433        // Android-changed: Support non-decimal starting digits.
434        String groupedNumeral = "("+nonZeroRadixDigits+digit+"?"+digit+"?("+
435                                groupSeparator+digit+digit+digit+")+)";
436        // digit++ is the possessive form which is necessary for reducing
437        // backtracking that would otherwise cause unacceptable performance
438        String numeral = "(("+ digit+"++)|"+groupedNumeral+")";
439        String javaStyleInteger = "([-+]?(" + numeral + "))";
440        String negativeInteger = negativePrefix + numeral + negativeSuffix;
441        String positiveInteger = positivePrefix + numeral + positiveSuffix;
442        return "("+ javaStyleInteger + ")|(" +
443            positiveInteger + ")|(" +
444            negativeInteger + ")";
445    }
446    private Pattern integerPattern() {
447        if (integerPattern == null) {
448            integerPattern = patternCache.forName(buildIntegerPatternString());
449        }
450        return integerPattern;
451    }
452
453    /**
454     * Fields and an accessor method to match line separators
455     */
456    private static volatile Pattern separatorPattern;
457    private static volatile Pattern linePattern;
458    private static final String LINE_SEPARATOR_PATTERN =
459                                           "\r\n|[\n\r\u2028\u2029\u0085]";
460    private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";
461
462    private static Pattern separatorPattern() {
463        Pattern sp = separatorPattern;
464        if (sp == null)
465            separatorPattern = sp = Pattern.compile(LINE_SEPARATOR_PATTERN);
466        return sp;
467    }
468
469    private static Pattern linePattern() {
470        Pattern lp = linePattern;
471        if (lp == null)
472            linePattern = lp = Pattern.compile(LINE_PATTERN);
473        return lp;
474    }
475
476    /**
477     * Fields and methods to match floats and doubles
478     */
479    private Pattern floatPattern;
480    private Pattern decimalPattern;
481    private void buildFloatAndDecimalPattern() {
482        // \\p{javaDigit} may not be perfect, see above
483        String digit = "([0-9]|(\\p{javaDigit}))";
484        String exponent = "([eE][+-]?"+digit+"+)?";
485        String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+
486                                groupSeparator+digit+digit+digit+")+)";
487        // Once again digit++ is used for performance, as above
488        String numeral = "(("+digit+"++)|"+groupedNumeral+")";
489        String decimalNumeral = "("+numeral+"|"+numeral +
490            decimalSeparator + digit + "*+|"+ decimalSeparator +
491            digit + "++)";
492        String nonNumber = "(NaN|"+nanString+"|Infinity|"+
493                               infinityString+")";
494        String positiveFloat = "(" + positivePrefix + decimalNumeral +
495                            positiveSuffix + exponent + ")";
496        String negativeFloat = "(" + negativePrefix + decimalNumeral +
497                            negativeSuffix + exponent + ")";
498        String decimal = "(([-+]?" + decimalNumeral + exponent + ")|"+
499            positiveFloat + "|" + negativeFloat + ")";
500        String hexFloat =
501            "[-+]?0[xX][0-9a-fA-F]*\\.[0-9a-fA-F]+([pP][-+]?[0-9]+)?";
502        String positiveNonNumber = "(" + positivePrefix + nonNumber +
503                            positiveSuffix + ")";
504        String negativeNonNumber = "(" + negativePrefix + nonNumber +
505                            negativeSuffix + ")";
506        String signedNonNumber = "(([-+]?"+nonNumber+")|" +
507                                 positiveNonNumber + "|" +
508                                 negativeNonNumber + ")";
509        floatPattern = Pattern.compile(decimal + "|" + hexFloat + "|" +
510                                       signedNonNumber);
511        decimalPattern = Pattern.compile(decimal);
512    }
513    private Pattern floatPattern() {
514        if (floatPattern == null) {
515            buildFloatAndDecimalPattern();
516        }
517        return floatPattern;
518    }
519    private Pattern decimalPattern() {
520        if (decimalPattern == null) {
521            buildFloatAndDecimalPattern();
522        }
523        return decimalPattern;
524    }
525
526    // Constructors
527
528    /**
529     * Constructs a <code>Scanner</code> that returns values scanned
530     * from the specified source delimited by the specified pattern.
531     *
532     * @param source A character source implementing the Readable interface
533     * @param pattern A delimiting pattern
534     */
535    private Scanner(Readable source, Pattern pattern) {
536        assert source != null : "source should not be null";
537        assert pattern != null : "pattern should not be null";
538        this.source = source;
539        delimPattern = pattern;
540        buf = CharBuffer.allocate(BUFFER_SIZE);
541        buf.limit(0);
542        matcher = delimPattern.matcher(buf);
543        matcher.useTransparentBounds(true);
544        matcher.useAnchoringBounds(false);
545        useLocale(Locale.getDefault(Locale.Category.FORMAT));
546    }
547
548    /**
549     * Constructs a new <code>Scanner</code> that produces values scanned
550     * from the specified source.
551     *
552     * @param  source A character source implementing the {@link Readable}
553     *         interface
554     */
555    public Scanner(Readable source) {
556        this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
557    }
558
559    /**
560     * Constructs a new <code>Scanner</code> that produces values scanned
561     * from the specified input stream. Bytes from the stream are converted
562     * into characters using the underlying platform's
563     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
564     *
565     * @param  source An input stream to be scanned
566     */
567    public Scanner(InputStream source) {
568        this(new InputStreamReader(source), WHITESPACE_PATTERN);
569    }
570
571    /**
572     * Constructs a new <code>Scanner</code> that produces values scanned
573     * from the specified input stream. Bytes from the stream are converted
574     * into characters using the specified charset.
575     *
576     * @param  source An input stream to be scanned
577     * @param charsetName The encoding type used to convert bytes from the
578     *        stream into characters to be scanned
579     * @throws IllegalArgumentException if the specified character set
580     *         does not exist
581     */
582    public Scanner(InputStream source, String charsetName) {
583        this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
584             WHITESPACE_PATTERN);
585    }
586
587    /**
588     * Returns a charset object for the given charset name.
589     * @throws NullPointerException          is csn is null
590     * @throws IllegalArgumentException      if the charset is not supported
591     */
592    private static Charset toCharset(String csn) {
593        Objects.requireNonNull(csn, "charsetName");
594        try {
595            return Charset.forName(csn);
596        } catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
597            // IllegalArgumentException should be thrown
598            throw new IllegalArgumentException(e);
599        }
600    }
601
602    private static Readable makeReadable(InputStream source, Charset charset) {
603        return new InputStreamReader(source, charset);
604    }
605
606    /**
607     * Constructs a new <code>Scanner</code> that produces values scanned
608     * from the specified file. Bytes from the file are converted into
609     * characters using the underlying platform's
610     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
611     *
612     * @param  source A file to be scanned
613     * @throws FileNotFoundException if source is not found
614     */
615    public Scanner(File source) throws FileNotFoundException {
616        this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
617    }
618
619    /**
620     * Constructs a new <code>Scanner</code> that produces values scanned
621     * from the specified file. Bytes from the file are converted into
622     * characters using the specified charset.
623     *
624     * @param  source A file to be scanned
625     * @param charsetName The encoding type used to convert bytes from the file
626     *        into characters to be scanned
627     * @throws FileNotFoundException if source is not found
628     * @throws IllegalArgumentException if the specified encoding is
629     *         not found
630     */
631    public Scanner(File source, String charsetName)
632        throws FileNotFoundException
633    {
634        this(Objects.requireNonNull(source), toDecoder(charsetName));
635    }
636
637    private Scanner(File source, CharsetDecoder dec)
638        throws FileNotFoundException
639    {
640        this(makeReadable((ReadableByteChannel)(new FileInputStream(source).getChannel()), dec));
641    }
642
643    private static CharsetDecoder toDecoder(String charsetName) {
644        // Android-changed: Throw an IAE instead of an NPE.
645        // Objects.requireNonNull(charsetName, "charsetName");
646        if (charsetName == null) {
647            throw new IllegalArgumentException("charsetName == null");
648        }
649        try {
650            return Charset.forName(charsetName).newDecoder();
651        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
652            throw new IllegalArgumentException(charsetName);
653        }
654    }
655
656    private static Readable makeReadable(ReadableByteChannel source,
657                                         CharsetDecoder dec) {
658        return Channels.newReader(source, dec, -1);
659    }
660
661    /**
662     * Constructs a new <code>Scanner</code> that produces values scanned
663     * from the specified file. Bytes from the file are converted into
664     * characters using the underlying platform's
665     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
666     *
667     * @param   source
668     *          the path to the file to be scanned
669     * @throws  IOException
670     *          if an I/O error occurs opening source
671     *
672     * @since   1.7
673     */
674    public Scanner(Path source)
675        throws IOException
676    {
677        this(Files.newInputStream(source));
678    }
679
680    /**
681     * Constructs a new <code>Scanner</code> that produces values scanned
682     * from the specified file. Bytes from the file are converted into
683     * characters using the specified charset.
684     *
685     * @param   source
686     *          the path to the file to be scanned
687     * @param   charsetName
688     *          The encoding type used to convert bytes from the file
689     *          into characters to be scanned
690     * @throws  IOException
691     *          if an I/O error occurs opening source
692     * @throws  IllegalArgumentException
693     *          if the specified encoding is not found
694     * @since   1.7
695     */
696    public Scanner(Path source, String charsetName) throws IOException {
697        this(Objects.requireNonNull(source), toCharset(charsetName));
698    }
699
700    private Scanner(Path source, Charset charset)  throws IOException {
701        this(makeReadable(Files.newInputStream(source), charset));
702    }
703
704    /**
705     * Constructs a new <code>Scanner</code> that produces values scanned
706     * from the specified string.
707     *
708     * @param  source A string to scan
709     */
710    public Scanner(String source) {
711        this(new StringReader(source), WHITESPACE_PATTERN);
712    }
713
714    /**
715     * Constructs a new <code>Scanner</code> that produces values scanned
716     * from the specified channel. Bytes from the source are converted into
717     * characters using the underlying platform's
718     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
719     *
720     * @param  source A channel to scan
721     */
722    public Scanner(ReadableByteChannel source) {
723        this(makeReadable(Objects.requireNonNull(source, "source")),
724             WHITESPACE_PATTERN);
725    }
726
727    private static Readable makeReadable(ReadableByteChannel source) {
728        return makeReadable(source, Charset.defaultCharset().newDecoder());
729    }
730
731    /**
732     * Constructs a new <code>Scanner</code> that produces values scanned
733     * from the specified channel. Bytes from the source are converted into
734     * characters using the specified charset.
735     *
736     * @param  source A channel to scan
737     * @param charsetName The encoding type used to convert bytes from the
738     *        channel into characters to be scanned
739     * @throws IllegalArgumentException if the specified character set
740     *         does not exist
741     */
742    public Scanner(ReadableByteChannel source, String charsetName) {
743        this(makeReadable(Objects.requireNonNull(source, "source"), toDecoder(charsetName)),
744             WHITESPACE_PATTERN);
745    }
746
747    // Private primitives used to support scanning
748
749    private void saveState() {
750        savedScannerPosition = position;
751    }
752
753    private void revertState() {
754        this.position = savedScannerPosition;
755        savedScannerPosition = -1;
756        skipped = false;
757    }
758
759    private boolean revertState(boolean b) {
760        this.position = savedScannerPosition;
761        savedScannerPosition = -1;
762        skipped = false;
763        return b;
764    }
765
766    private void cacheResult() {
767        hasNextResult = matcher.group();
768        hasNextPosition = matcher.end();
769        hasNextPattern = matcher.pattern();
770    }
771
772    private void cacheResult(String result) {
773        hasNextResult = result;
774        hasNextPosition = matcher.end();
775        hasNextPattern = matcher.pattern();
776    }
777
778    // Clears both regular cache and type cache
779    private void clearCaches() {
780        hasNextPattern = null;
781        typeCache = null;
782    }
783
784    // Also clears both the regular cache and the type cache
785    private String getCachedResult() {
786        position = hasNextPosition;
787        hasNextPattern = null;
788        typeCache = null;
789        return hasNextResult;
790    }
791
792    // Also clears both the regular cache and the type cache
793    private void useTypeCache() {
794        if (closed)
795            throw new IllegalStateException("Scanner closed");
796        position = hasNextPosition;
797        hasNextPattern = null;
798        typeCache = null;
799    }
800
801    // Tries to read more input. May block.
802    private void readInput() {
803        if (buf.limit() == buf.capacity())
804            makeSpace();
805
806        // Prepare to receive data
807        int p = buf.position();
808        buf.position(buf.limit());
809        buf.limit(buf.capacity());
810
811        int n = 0;
812        try {
813            n = source.read(buf);
814        } catch (IOException ioe) {
815            lastException = ioe;
816            n = -1;
817        }
818
819        if (n == -1) {
820            sourceClosed = true;
821            needInput = false;
822        }
823
824        if (n > 0)
825            needInput = false;
826
827        // Restore current position and limit for reading
828        buf.limit(buf.position());
829        buf.position(p);
830        // Android-changed: The matcher implementation eagerly calls toString() so we'll have
831        // to update its input whenever the buffer limit, position etc. changes.
832        matcher.reset(buf);
833    }
834
835    // After this method is called there will either be an exception
836    // or else there will be space in the buffer
837    private boolean makeSpace() {
838        clearCaches();
839        int offset = savedScannerPosition == -1 ?
840            position : savedScannerPosition;
841        buf.position(offset);
842        // Gain space by compacting buffer
843        if (offset > 0) {
844            buf.compact();
845            translateSavedIndexes(offset);
846            position -= offset;
847            buf.flip();
848            return true;
849        }
850        // Gain space by growing buffer
851        int newSize = buf.capacity() * 2;
852        CharBuffer newBuf = CharBuffer.allocate(newSize);
853        newBuf.put(buf);
854        newBuf.flip();
855        translateSavedIndexes(offset);
856        position -= offset;
857        buf = newBuf;
858        matcher.reset(buf);
859        return true;
860    }
861
862    // When a buffer compaction/reallocation occurs the saved indexes must
863    // be modified appropriately
864    private void translateSavedIndexes(int offset) {
865        if (savedScannerPosition != -1)
866            savedScannerPosition -= offset;
867    }
868
869    // If we are at the end of input then NoSuchElement;
870    // If there is still input left then InputMismatch
871    private void throwFor() {
872        skipped = false;
873        if ((sourceClosed) && (position == buf.limit()))
874            throw new NoSuchElementException();
875        else
876            throw new InputMismatchException();
877    }
878
879    // Returns true if a complete token or partial token is in the buffer.
880    // It is not necessary to find a complete token since a partial token
881    // means that there will be another token with or without more input.
882    private boolean hasTokenInBuffer() {
883        matchValid = false;
884        matcher.usePattern(delimPattern);
885        matcher.region(position, buf.limit());
886
887        // Skip delims first
888        if (matcher.lookingAt())
889            position = matcher.end();
890
891        // If we are sitting at the end, no more tokens in buffer
892        if (position == buf.limit())
893            return false;
894
895        return true;
896    }
897
898    /*
899     * Returns a "complete token" that matches the specified pattern
900     *
901     * A token is complete if surrounded by delims; a partial token
902     * is prefixed by delims but not postfixed by them
903     *
904     * The position is advanced to the end of that complete token
905     *
906     * Pattern == null means accept any token at all
907     *
908     * Triple return:
909     * 1. valid string means it was found
910     * 2. null with needInput=false means we won't ever find it
911     * 3. null with needInput=true means try again after readInput
912     */
913    private String getCompleteTokenInBuffer(Pattern pattern) {
914        matchValid = false;
915
916        // Skip delims first
917        matcher.usePattern(delimPattern);
918        if (!skipped) { // Enforcing only one skip of leading delims
919            matcher.region(position, buf.limit());
920            if (matcher.lookingAt()) {
921                // If more input could extend the delimiters then we must wait
922                // for more input
923                if (matcher.hitEnd() && !sourceClosed) {
924                    needInput = true;
925                    return null;
926                }
927                // The delims were whole and the matcher should skip them
928                skipped = true;
929                position = matcher.end();
930            }
931        }
932
933        // If we are sitting at the end, no more tokens in buffer
934        if (position == buf.limit()) {
935            if (sourceClosed)
936                return null;
937            needInput = true;
938            return null;
939        }
940
941        // Must look for next delims. Simply attempting to match the
942        // pattern at this point may find a match but it might not be
943        // the first longest match because of missing input, or it might
944        // match a partial token instead of the whole thing.
945
946        // Then look for next delims
947        matcher.region(position, buf.limit());
948        boolean foundNextDelim = matcher.find();
949        if (foundNextDelim && (matcher.end() == position)) {
950            // Zero length delimiter match; we should find the next one
951            // using the automatic advance past a zero length match;
952            // Otherwise we have just found the same one we just skipped
953            foundNextDelim = matcher.find();
954        }
955        if (foundNextDelim) {
956            // In the rare case that more input could cause the match
957            // to be lost and there is more input coming we must wait
958            // for more input. Note that hitting the end is okay as long
959            // as the match cannot go away. It is the beginning of the
960            // next delims we want to be sure about, we don't care if
961            // they potentially extend further.
962            if (matcher.requireEnd() && !sourceClosed) {
963                needInput = true;
964                return null;
965            }
966            int tokenEnd = matcher.start();
967            // There is a complete token.
968            if (pattern == null) {
969                // Must continue with match to provide valid MatchResult
970                pattern = FIND_ANY_PATTERN;
971            }
972            //  Attempt to match against the desired pattern
973            matcher.usePattern(pattern);
974            matcher.region(position, tokenEnd);
975            if (matcher.matches()) {
976                String s = matcher.group();
977                position = matcher.end();
978                return s;
979            } else { // Complete token but it does not match
980                return null;
981            }
982        }
983
984        // If we can't find the next delims but no more input is coming,
985        // then we can treat the remainder as a whole token
986        if (sourceClosed) {
987            if (pattern == null) {
988                // Must continue with match to provide valid MatchResult
989                pattern = FIND_ANY_PATTERN;
990            }
991            // Last token; Match the pattern here or throw
992            matcher.usePattern(pattern);
993            matcher.region(position, buf.limit());
994            if (matcher.matches()) {
995                String s = matcher.group();
996                position = matcher.end();
997                return s;
998            }
999            // Last piece does not match
1000            return null;
1001        }
1002
1003        // There is a partial token in the buffer; must read more
1004        // to complete it
1005        needInput = true;
1006        return null;
1007    }
1008
1009    // Finds the specified pattern in the buffer up to horizon.
1010    // Returns a match for the specified input pattern.
1011    private String findPatternInBuffer(Pattern pattern, int horizon) {
1012        matchValid = false;
1013        matcher.usePattern(pattern);
1014        int bufferLimit = buf.limit();
1015        int horizonLimit = -1;
1016        int searchLimit = bufferLimit;
1017        if (horizon > 0) {
1018            horizonLimit = position + horizon;
1019            if (horizonLimit < bufferLimit)
1020                searchLimit = horizonLimit;
1021        }
1022        matcher.region(position, searchLimit);
1023        if (matcher.find()) {
1024            if (matcher.hitEnd() && (!sourceClosed)) {
1025                // The match may be longer if didn't hit horizon or real end
1026                if (searchLimit != horizonLimit) {
1027                     // Hit an artificial end; try to extend the match
1028                    needInput = true;
1029                    return null;
1030                }
1031                // The match could go away depending on what is next
1032                if ((searchLimit == horizonLimit) && matcher.requireEnd()) {
1033                    // Rare case: we hit the end of input and it happens
1034                    // that it is at the horizon and the end of input is
1035                    // required for the match.
1036                    needInput = true;
1037                    return null;
1038                }
1039            }
1040            // Did not hit end, or hit real end, or hit horizon
1041            position = matcher.end();
1042            return matcher.group();
1043        }
1044
1045        if (sourceClosed)
1046            return null;
1047
1048        // If there is no specified horizon, or if we have not searched
1049        // to the specified horizon yet, get more input
1050        if ((horizon == 0) || (searchLimit != horizonLimit))
1051            needInput = true;
1052        return null;
1053    }
1054
1055    // Returns a match for the specified input pattern anchored at
1056    // the current position
1057    private String matchPatternInBuffer(Pattern pattern) {
1058        matchValid = false;
1059        matcher.usePattern(pattern);
1060        matcher.region(position, buf.limit());
1061        if (matcher.lookingAt()) {
1062            if (matcher.hitEnd() && (!sourceClosed)) {
1063                // Get more input and try again
1064                needInput = true;
1065                return null;
1066            }
1067            position = matcher.end();
1068            return matcher.group();
1069        }
1070
1071        if (sourceClosed)
1072            return null;
1073
1074        // Read more to find pattern
1075        needInput = true;
1076        return null;
1077    }
1078
1079    // Throws if the scanner is closed
1080    private void ensureOpen() {
1081        if (closed)
1082            throw new IllegalStateException("Scanner closed");
1083    }
1084
1085    // Public methods
1086
1087    /**
1088     * Closes this scanner.
1089     *
1090     * <p> If this scanner has not yet been closed then if its underlying
1091     * {@linkplain java.lang.Readable readable} also implements the {@link
1092     * java.io.Closeable} interface then the readable's <tt>close</tt> method
1093     * will be invoked.  If this scanner is already closed then invoking this
1094     * method will have no effect.
1095     *
1096     * <p>Attempting to perform search operations after a scanner has
1097     * been closed will result in an {@link IllegalStateException}.
1098     *
1099     */
1100    public void close() {
1101        if (closed)
1102            return;
1103        if (source instanceof Closeable) {
1104            try {
1105                ((Closeable)source).close();
1106            } catch (IOException ioe) {
1107                lastException = ioe;
1108            }
1109        }
1110        sourceClosed = true;
1111        source = null;
1112        closed = true;
1113    }
1114
1115    /**
1116     * Returns the <code>IOException</code> last thrown by this
1117     * <code>Scanner</code>'s underlying <code>Readable</code>. This method
1118     * returns <code>null</code> if no such exception exists.
1119     *
1120     * @return the last exception thrown by this scanner's readable
1121     */
1122    public IOException ioException() {
1123        return lastException;
1124    }
1125
1126    /**
1127     * Returns the <code>Pattern</code> this <code>Scanner</code> is currently
1128     * using to match delimiters.
1129     *
1130     * @return this scanner's delimiting pattern.
1131     */
1132    public Pattern delimiter() {
1133        return delimPattern;
1134    }
1135
1136    /**
1137     * Sets this scanner's delimiting pattern to the specified pattern.
1138     *
1139     * @param pattern A delimiting pattern
1140     * @return this scanner
1141     */
1142    public Scanner useDelimiter(Pattern pattern) {
1143        delimPattern = pattern;
1144        return this;
1145    }
1146
1147    /**
1148     * Sets this scanner's delimiting pattern to a pattern constructed from
1149     * the specified <code>String</code>.
1150     *
1151     * <p> An invocation of this method of the form
1152     * <tt>useDelimiter(pattern)</tt> behaves in exactly the same way as the
1153     * invocation <tt>useDelimiter(Pattern.compile(pattern))</tt>.
1154     *
1155     * <p> Invoking the {@link #reset} method will set the scanner's delimiter
1156     * to the <a href= "#default-delimiter">default</a>.
1157     *
1158     * @param pattern A string specifying a delimiting pattern
1159     * @return this scanner
1160     */
1161    public Scanner useDelimiter(String pattern) {
1162        delimPattern = patternCache.forName(pattern);
1163        return this;
1164    }
1165
1166    /**
1167     * Returns this scanner's 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     * @return this scanner's locale
1174     */
1175    public Locale locale() {
1176        return this.locale;
1177    }
1178
1179    /**
1180     * Sets this scanner's locale to the specified locale.
1181     *
1182     * <p>A scanner's locale affects many elements of its default
1183     * primitive matching regular expressions; see
1184     * <a href= "#localized-numbers">localized numbers</a> above.
1185     *
1186     * <p>Invoking the {@link #reset} method will set the scanner's locale to
1187     * the <a href= "#initial-locale">initial locale</a>.
1188     *
1189     * @param locale A string specifying the locale to use
1190     * @return this scanner
1191     */
1192    public Scanner useLocale(Locale locale) {
1193        if (locale.equals(this.locale))
1194            return this;
1195
1196        this.locale = locale;
1197        DecimalFormat df =
1198            (DecimalFormat)NumberFormat.getNumberInstance(locale);
1199        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
1200
1201        // These must be literalized to avoid collision with regex
1202        // metacharacters such as dot or parenthesis
1203        groupSeparator =   "\\" + dfs.getGroupingSeparator();
1204        decimalSeparator = "\\" + dfs.getDecimalSeparator();
1205
1206        // Quoting the nonzero length locale-specific things
1207        // to avoid potential conflict with metacharacters
1208        nanString = "\\Q" + dfs.getNaN() + "\\E";
1209        infinityString = "\\Q" + dfs.getInfinity() + "\\E";
1210        positivePrefix = df.getPositivePrefix();
1211        if (positivePrefix.length() > 0)
1212            positivePrefix = "\\Q" + positivePrefix + "\\E";
1213        negativePrefix = df.getNegativePrefix();
1214        if (negativePrefix.length() > 0)
1215            negativePrefix = "\\Q" + negativePrefix + "\\E";
1216        positiveSuffix = df.getPositiveSuffix();
1217        if (positiveSuffix.length() > 0)
1218            positiveSuffix = "\\Q" + positiveSuffix + "\\E";
1219        negativeSuffix = df.getNegativeSuffix();
1220        if (negativeSuffix.length() > 0)
1221            negativeSuffix = "\\Q" + negativeSuffix + "\\E";
1222
1223        // Force rebuilding and recompilation of locale dependent
1224        // primitive patterns
1225        integerPattern = null;
1226        floatPattern = null;
1227
1228        return this;
1229    }
1230
1231    /**
1232     * Returns this scanner's default radix.
1233     *
1234     * <p>A scanner's radix affects elements of its default
1235     * number matching regular expressions; see
1236     * <a href= "#localized-numbers">localized numbers</a> above.
1237     *
1238     * @return the default radix of this scanner
1239     */
1240    public int radix() {
1241        return this.defaultRadix;
1242    }
1243
1244    /**
1245     * Sets this scanner's default radix to the specified radix.
1246     *
1247     * <p>A scanner's radix affects elements of its default
1248     * number matching regular expressions; see
1249     * <a href= "#localized-numbers">localized numbers</a> above.
1250     *
1251     * <p>If the radix is less than <code>Character.MIN_RADIX</code>
1252     * or greater than <code>Character.MAX_RADIX</code>, then an
1253     * <code>IllegalArgumentException</code> is thrown.
1254     *
1255     * <p>Invoking the {@link #reset} method will set the scanner's radix to
1256     * <code>10</code>.
1257     *
1258     * @param radix The radix to use when scanning numbers
1259     * @return this scanner
1260     * @throws IllegalArgumentException if radix is out of range
1261     */
1262    public Scanner useRadix(int radix) {
1263        if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX))
1264            throw new IllegalArgumentException("radix:"+radix);
1265
1266        if (this.defaultRadix == radix)
1267            return this;
1268        this.defaultRadix = radix;
1269        // Force rebuilding and recompilation of radix dependent patterns
1270        integerPattern = null;
1271        return this;
1272    }
1273
1274    // The next operation should occur in the specified radix but
1275    // the default is left untouched.
1276    private void setRadix(int radix) {
1277        // Android-changed: Complain loudly if a bogus radix is being set.
1278        if (radix > Character.MAX_RADIX) {
1279            throw new IllegalArgumentException("radix == " + radix);
1280        }
1281
1282        if (this.radix != radix) {
1283            // Force rebuilding and recompilation of radix dependent patterns
1284            integerPattern = null;
1285            this.radix = radix;
1286        }
1287    }
1288
1289    /**
1290     * Returns the match result of the last scanning operation performed
1291     * by this scanner. This method throws <code>IllegalStateException</code>
1292     * if no match has been performed, or if the last match was
1293     * not successful.
1294     *
1295     * <p>The various <code>next</code>methods of <code>Scanner</code>
1296     * make a match result available if they complete without throwing an
1297     * exception. For instance, after an invocation of the {@link #nextInt}
1298     * method that returned an int, this method returns a
1299     * <code>MatchResult</code> for the search of the
1300     * <a href="#Integer-regex"><i>Integer</i></a> regular expression
1301     * defined above. Similarly the {@link #findInLine},
1302     * {@link #findWithinHorizon}, and {@link #skip} methods will make a
1303     * match available if they succeed.
1304     *
1305     * @return a match result for the last match operation
1306     * @throws IllegalStateException  If no match result is available
1307     */
1308    public MatchResult match() {
1309        if (!matchValid)
1310            throw new IllegalStateException("No match result available");
1311        return matcher.toMatchResult();
1312    }
1313
1314    /**
1315     * <p>Returns the string representation of this <code>Scanner</code>. The
1316     * string representation of a <code>Scanner</code> contains information
1317     * that may be useful for debugging. The exact format is unspecified.
1318     *
1319     * @return  The string representation of this scanner
1320     */
1321    public String toString() {
1322        StringBuilder sb = new StringBuilder();
1323        sb.append("java.util.Scanner");
1324        sb.append("[delimiters=" + delimPattern + "]");
1325        sb.append("[position=" + position + "]");
1326        sb.append("[match valid=" + matchValid + "]");
1327        sb.append("[need input=" + needInput + "]");
1328        sb.append("[source closed=" + sourceClosed + "]");
1329        sb.append("[skipped=" + skipped + "]");
1330        sb.append("[group separator=" + groupSeparator + "]");
1331        sb.append("[decimal separator=" + decimalSeparator + "]");
1332        sb.append("[positive prefix=" + positivePrefix + "]");
1333        sb.append("[negative prefix=" + negativePrefix + "]");
1334        sb.append("[positive suffix=" + positiveSuffix + "]");
1335        sb.append("[negative suffix=" + negativeSuffix + "]");
1336        sb.append("[NaN string=" + nanString + "]");
1337        sb.append("[infinity string=" + infinityString + "]");
1338        return sb.toString();
1339    }
1340
1341    /**
1342     * Returns true if this scanner has another token in its input.
1343     * This method may block while waiting for input to scan.
1344     * The scanner does not advance past any input.
1345     *
1346     * @return true if and only if this scanner has another token
1347     * @throws IllegalStateException if this scanner is closed
1348     * @see java.util.Iterator
1349     */
1350    public boolean hasNext() {
1351        ensureOpen();
1352        saveState();
1353        while (!sourceClosed) {
1354            if (hasTokenInBuffer())
1355                return revertState(true);
1356            readInput();
1357        }
1358        boolean result = hasTokenInBuffer();
1359        return revertState(result);
1360    }
1361
1362    /**
1363     * Finds and returns the next complete token from this scanner.
1364     * A complete token is preceded and followed by input that matches
1365     * the delimiter pattern. This method may block while waiting for input
1366     * to scan, even if a previous invocation of {@link #hasNext} returned
1367     * <code>true</code>.
1368     *
1369     * @return the next token
1370     * @throws NoSuchElementException if no more tokens are available
1371     * @throws IllegalStateException if this scanner is closed
1372     * @see java.util.Iterator
1373     */
1374    public String next() {
1375        ensureOpen();
1376        clearCaches();
1377
1378        while (true) {
1379            String token = getCompleteTokenInBuffer(null);
1380            if (token != null) {
1381                matchValid = true;
1382                skipped = false;
1383                return token;
1384            }
1385            if (needInput)
1386                readInput();
1387            else
1388                throwFor();
1389        }
1390    }
1391
1392    /**
1393     * The remove operation is not supported by this implementation of
1394     * <code>Iterator</code>.
1395     *
1396     * @throws UnsupportedOperationException if this method is invoked.
1397     * @see java.util.Iterator
1398     */
1399    public void remove() {
1400        throw new UnsupportedOperationException();
1401    }
1402
1403    /**
1404     * Returns true if the next token matches the pattern constructed from the
1405     * specified string. The scanner does not advance past any input.
1406     *
1407     * <p> An invocation of this method of the form <tt>hasNext(pattern)</tt>
1408     * behaves in exactly the same way as the invocation
1409     * <tt>hasNext(Pattern.compile(pattern))</tt>.
1410     *
1411     * @param pattern a string specifying the pattern to scan
1412     * @return true if and only if this scanner has another token matching
1413     *         the specified pattern
1414     * @throws IllegalStateException if this scanner is closed
1415     */
1416    public boolean hasNext(String pattern)  {
1417        return hasNext(patternCache.forName(pattern));
1418    }
1419
1420    /**
1421     * Returns the next token if it matches the pattern constructed from the
1422     * specified string.  If the match is successful, the scanner advances
1423     * past the input that matched the pattern.
1424     *
1425     * <p> An invocation of this method of the form <tt>next(pattern)</tt>
1426     * behaves in exactly the same way as the invocation
1427     * <tt>next(Pattern.compile(pattern))</tt>.
1428     *
1429     * @param pattern a string specifying the pattern to scan
1430     * @return the next token
1431     * @throws NoSuchElementException if no such tokens are available
1432     * @throws IllegalStateException if this scanner is closed
1433     */
1434    public String next(String pattern)  {
1435        return next(patternCache.forName(pattern));
1436    }
1437
1438    /**
1439     * Returns true if the next complete token matches the specified pattern.
1440     * A complete token is prefixed and postfixed by input that matches
1441     * the delimiter pattern. This method may block while waiting for input.
1442     * The scanner does not advance past any input.
1443     *
1444     * @param pattern the pattern to scan for
1445     * @return true if and only if this scanner has another token matching
1446     *         the specified pattern
1447     * @throws IllegalStateException if this scanner is closed
1448     */
1449    public boolean hasNext(Pattern pattern) {
1450        ensureOpen();
1451        if (pattern == null)
1452            throw new NullPointerException();
1453        hasNextPattern = null;
1454        saveState();
1455
1456        while (true) {
1457            if (getCompleteTokenInBuffer(pattern) != null) {
1458                matchValid = true;
1459                cacheResult();
1460                return revertState(true);
1461            }
1462            if (needInput)
1463                readInput();
1464            else
1465                return revertState(false);
1466        }
1467    }
1468
1469    /**
1470     * Returns the next token if it matches the specified pattern. This
1471     * method may block while waiting for input to scan, even if a previous
1472     * invocation of {@link #hasNext(Pattern)} returned <code>true</code>.
1473     * If the match is successful, the scanner advances past the input that
1474     * matched the pattern.
1475     *
1476     * @param pattern the pattern to scan for
1477     * @return the next token
1478     * @throws NoSuchElementException if no more tokens are available
1479     * @throws IllegalStateException if this scanner is closed
1480     */
1481    public String next(Pattern pattern) {
1482        ensureOpen();
1483        if (pattern == null)
1484            throw new NullPointerException();
1485
1486        // Did we already find this pattern?
1487        if (hasNextPattern == pattern)
1488            return getCachedResult();
1489        clearCaches();
1490
1491        // Search for the pattern
1492        while (true) {
1493            String token = getCompleteTokenInBuffer(pattern);
1494            if (token != null) {
1495                matchValid = true;
1496                skipped = false;
1497                return token;
1498            }
1499            if (needInput)
1500                readInput();
1501            else
1502                throwFor();
1503        }
1504    }
1505
1506    /**
1507     * Returns true if there is another line in the input of this scanner.
1508     * This method may block while waiting for input. The scanner does not
1509     * advance past any input.
1510     *
1511     * @return true if and only if this scanner has another line of input
1512     * @throws IllegalStateException if this scanner is closed
1513     */
1514    public boolean hasNextLine() {
1515        saveState();
1516
1517        String result = findWithinHorizon(linePattern(), 0);
1518        if (result != null) {
1519            MatchResult mr = this.match();
1520            String lineSep = mr.group(1);
1521            if (lineSep != null) {
1522                result = result.substring(0, result.length() -
1523                                          lineSep.length());
1524                cacheResult(result);
1525
1526            } else {
1527                cacheResult();
1528            }
1529        }
1530        revertState();
1531        return (result != null);
1532    }
1533
1534    /**
1535     * Advances this scanner past the current line and returns the input
1536     * that was skipped.
1537     *
1538     * This method returns the rest of the current line, excluding any line
1539     * separator at the end. The position is set to the beginning of the next
1540     * line.
1541     *
1542     * <p>Since this method continues to search through the input looking
1543     * for a line separator, it may buffer all of the input searching for
1544     * the line to skip if no line separators are present.
1545     *
1546     * @return the line that was skipped
1547     * @throws NoSuchElementException if no line was found
1548     * @throws IllegalStateException if this scanner is closed
1549     */
1550    public String nextLine() {
1551        if (hasNextPattern == linePattern())
1552            return getCachedResult();
1553        clearCaches();
1554
1555        String result = findWithinHorizon(linePattern, 0);
1556        if (result == null)
1557            throw new NoSuchElementException("No line found");
1558        MatchResult mr = this.match();
1559        String lineSep = mr.group(1);
1560        if (lineSep != null)
1561            result = result.substring(0, result.length() - lineSep.length());
1562        if (result == null)
1563            throw new NoSuchElementException();
1564        else
1565            return result;
1566    }
1567
1568    // Public methods that ignore delimiters
1569
1570    /**
1571     * Attempts to find the next occurrence of a pattern constructed from the
1572     * specified string, ignoring delimiters.
1573     *
1574     * <p>An invocation of this method of the form <tt>findInLine(pattern)</tt>
1575     * behaves in exactly the same way as the invocation
1576     * <tt>findInLine(Pattern.compile(pattern))</tt>.
1577     *
1578     * @param pattern a string specifying the pattern to search for
1579     * @return the text that matched the specified pattern
1580     * @throws IllegalStateException if this scanner is closed
1581     */
1582    public String findInLine(String pattern) {
1583        return findInLine(patternCache.forName(pattern));
1584    }
1585
1586    /**
1587     * Attempts to find the next occurrence of the specified pattern ignoring
1588     * delimiters. If the pattern is found before the next line separator, the
1589     * scanner advances past the input that matched and returns the string that
1590     * matched the pattern.
1591     * If no such pattern is detected in the input up to the next line
1592     * separator, then <code>null</code> is returned and the scanner's
1593     * position is unchanged. This method may block waiting for input that
1594     * matches the pattern.
1595     *
1596     * <p>Since this method continues to search through the input looking
1597     * for the specified pattern, it may buffer all of the input searching for
1598     * the desired token if no line separators are present.
1599     *
1600     * @param pattern the pattern to scan for
1601     * @return the text that matched the specified pattern
1602     * @throws IllegalStateException if this scanner is closed
1603     */
1604    public String findInLine(Pattern pattern) {
1605        ensureOpen();
1606        if (pattern == null)
1607            throw new NullPointerException();
1608        clearCaches();
1609        // Expand buffer to include the next newline or end of input
1610        int endPosition = 0;
1611        saveState();
1612        while (true) {
1613            String token = findPatternInBuffer(separatorPattern(), 0);
1614            if (token != null) {
1615                endPosition = matcher.start();
1616                break; // up to next newline
1617            }
1618            if (needInput) {
1619                readInput();
1620            } else {
1621                endPosition = buf.limit();
1622                break; // up to end of input
1623            }
1624        }
1625        revertState();
1626        int horizonForLine = endPosition - position;
1627        // If there is nothing between the current pos and the next
1628        // newline simply return null, invoking findWithinHorizon
1629        // with "horizon=0" will scan beyond the line bound.
1630        if (horizonForLine == 0)
1631            return null;
1632        // Search for the pattern
1633        return findWithinHorizon(pattern, horizonForLine);
1634    }
1635
1636    /**
1637     * Attempts to find the next occurrence of a pattern constructed from the
1638     * specified string, ignoring delimiters.
1639     *
1640     * <p>An invocation of this method of the form
1641     * <tt>findWithinHorizon(pattern)</tt> behaves in exactly the same way as
1642     * the invocation
1643     * <tt>findWithinHorizon(Pattern.compile(pattern, horizon))</tt>.
1644     *
1645     * @param pattern a string specifying the pattern to search for
1646     * @param horizon the search horizon
1647     * @return the text that matched the specified pattern
1648     * @throws IllegalStateException if this scanner is closed
1649     * @throws IllegalArgumentException if horizon is negative
1650     */
1651    public String findWithinHorizon(String pattern, int horizon) {
1652        return findWithinHorizon(patternCache.forName(pattern), horizon);
1653    }
1654
1655    /**
1656     * Attempts to find the next occurrence of the specified pattern.
1657     *
1658     * <p>This method searches through the input up to the specified
1659     * search horizon, ignoring delimiters. If the pattern is found the
1660     * scanner advances past the input that matched and returns the string
1661     * that matched the pattern. If no such pattern is detected then the
1662     * null is returned and the scanner's position remains unchanged. This
1663     * method may block waiting for input that matches the pattern.
1664     *
1665     * <p>A scanner will never search more than <code>horizon</code> code
1666     * points beyond its current position. Note that a match may be clipped
1667     * by the horizon; that is, an arbitrary match result may have been
1668     * different if the horizon had been larger. The scanner treats the
1669     * horizon as a transparent, non-anchoring bound (see {@link
1670     * Matcher#useTransparentBounds} and {@link Matcher#useAnchoringBounds}).
1671     *
1672     * <p>If horizon is <code>0</code>, then the horizon is ignored and
1673     * this method continues to search through the input looking for the
1674     * specified pattern without bound. In this case it may buffer all of
1675     * the input searching for the pattern.
1676     *
1677     * <p>If horizon is negative, then an IllegalArgumentException is
1678     * thrown.
1679     *
1680     * @param pattern the pattern to scan for
1681     * @param horizon the search horizon
1682     * @return the text that matched the specified pattern
1683     * @throws IllegalStateException if this scanner is closed
1684     * @throws IllegalArgumentException if horizon is negative
1685     */
1686    public String findWithinHorizon(Pattern pattern, int horizon) {
1687        ensureOpen();
1688        if (pattern == null)
1689            throw new NullPointerException();
1690        if (horizon < 0)
1691            throw new IllegalArgumentException("horizon < 0");
1692        clearCaches();
1693
1694        // Search for the pattern
1695        while (true) {
1696            String token = findPatternInBuffer(pattern, horizon);
1697            if (token != null) {
1698                matchValid = true;
1699                return token;
1700            }
1701            if (needInput)
1702                readInput();
1703            else
1704                break; // up to end of input
1705        }
1706        return null;
1707    }
1708
1709    /**
1710     * Skips input that matches the specified pattern, ignoring delimiters.
1711     * This method will skip input if an anchored match of the specified
1712     * pattern succeeds.
1713     *
1714     * <p>If a match to the specified pattern is not found at the
1715     * current position, then no input is skipped and a
1716     * <tt>NoSuchElementException</tt> is thrown.
1717     *
1718     * <p>Since this method seeks to match the specified pattern starting at
1719     * the scanner's current position, patterns that can match a lot of
1720     * input (".*", for example) may cause the scanner to buffer a large
1721     * amount of input.
1722     *
1723     * <p>Note that it is possible to skip something without risking a
1724     * <code>NoSuchElementException</code> by using a pattern that can
1725     * match nothing, e.g., <code>sc.skip("[ \t]*")</code>.
1726     *
1727     * @param pattern a string specifying the pattern to skip over
1728     * @return this scanner
1729     * @throws NoSuchElementException if the specified pattern is not found
1730     * @throws IllegalStateException if this scanner is closed
1731     */
1732    public Scanner skip(Pattern pattern) {
1733        ensureOpen();
1734        if (pattern == null)
1735            throw new NullPointerException();
1736        clearCaches();
1737
1738        // Search for the pattern
1739        while (true) {
1740            String token = matchPatternInBuffer(pattern);
1741            if (token != null) {
1742                matchValid = true;
1743                position = matcher.end();
1744                return this;
1745            }
1746            if (needInput)
1747                readInput();
1748            else
1749                throw new NoSuchElementException();
1750        }
1751    }
1752
1753    /**
1754     * Skips input that matches a pattern constructed from the specified
1755     * string.
1756     *
1757     * <p> An invocation of this method of the form <tt>skip(pattern)</tt>
1758     * behaves in exactly the same way as the invocation
1759     * <tt>skip(Pattern.compile(pattern))</tt>.
1760     *
1761     * @param pattern a string specifying the pattern to skip over
1762     * @return this scanner
1763     * @throws IllegalStateException if this scanner is closed
1764     */
1765    public Scanner skip(String pattern) {
1766        return skip(patternCache.forName(pattern));
1767    }
1768
1769    // Convenience methods for scanning primitives
1770
1771    /**
1772     * Returns true if the next token in this scanner's input can be
1773     * interpreted as a boolean value using a case insensitive pattern
1774     * created from the string "true|false".  The scanner does not
1775     * advance past the input that matched.
1776     *
1777     * @return true if and only if this scanner's next token is a valid
1778     *         boolean value
1779     * @throws IllegalStateException if this scanner is closed
1780     */
1781    public boolean hasNextBoolean()  {
1782        return hasNext(boolPattern());
1783    }
1784
1785    /**
1786     * Scans the next token of the input into a boolean value and returns
1787     * that value. This method will throw <code>InputMismatchException</code>
1788     * if the next token cannot be translated into a valid boolean value.
1789     * If the match is successful, the scanner advances past the input that
1790     * matched.
1791     *
1792     * @return the boolean scanned from the input
1793     * @throws InputMismatchException if the next token is not a valid boolean
1794     * @throws NoSuchElementException if input is exhausted
1795     * @throws IllegalStateException if this scanner is closed
1796     */
1797    public boolean nextBoolean()  {
1798        clearCaches();
1799        return Boolean.parseBoolean(next(boolPattern()));
1800    }
1801
1802    /**
1803     * Returns true if the next token in this scanner's input can be
1804     * interpreted as a byte value in the default radix using the
1805     * {@link #nextByte} method. The scanner does not advance past any input.
1806     *
1807     * @return true if and only if this scanner's next token is a valid
1808     *         byte value
1809     * @throws IllegalStateException if this scanner is closed
1810     */
1811    public boolean hasNextByte() {
1812        return hasNextByte(defaultRadix);
1813    }
1814
1815    /**
1816     * Returns true if the next token in this scanner's input can be
1817     * interpreted as a byte value in the specified radix using the
1818     * {@link #nextByte} method. The scanner does not advance past any input.
1819     *
1820     * @param radix the radix used to interpret the token as a byte value
1821     * @return true if and only if this scanner's next token is a valid
1822     *         byte value
1823     * @throws IllegalStateException if this scanner is closed
1824     */
1825    public boolean hasNextByte(int radix) {
1826        setRadix(radix);
1827        boolean result = hasNext(integerPattern());
1828        if (result) { // Cache it
1829            try {
1830                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1831                    processIntegerToken(hasNextResult) :
1832                    hasNextResult;
1833                typeCache = Byte.parseByte(s, radix);
1834            } catch (NumberFormatException nfe) {
1835                result = false;
1836            }
1837        }
1838        return result;
1839    }
1840
1841    /**
1842     * Scans the next token of the input as a <tt>byte</tt>.
1843     *
1844     * <p> An invocation of this method of the form
1845     * <tt>nextByte()</tt> behaves in exactly the same way as the
1846     * invocation <tt>nextByte(radix)</tt>, where <code>radix</code>
1847     * is the default radix of this scanner.
1848     *
1849     * @return the <tt>byte</tt> scanned from the input
1850     * @throws InputMismatchException
1851     *         if the next token does not match the <i>Integer</i>
1852     *         regular expression, or is out of range
1853     * @throws NoSuchElementException if input is exhausted
1854     * @throws IllegalStateException if this scanner is closed
1855     */
1856    public byte nextByte() {
1857         return nextByte(defaultRadix);
1858    }
1859
1860    /**
1861     * Scans the next token of the input as a <tt>byte</tt>.
1862     * This method will throw <code>InputMismatchException</code>
1863     * if the next token cannot be translated into a valid byte value as
1864     * described below. If the translation is successful, the scanner advances
1865     * past the input that matched.
1866     *
1867     * <p> If the next token matches the <a
1868     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
1869     * above then the token is converted into a <tt>byte</tt> value as if by
1870     * removing all locale specific prefixes, group separators, and locale
1871     * specific suffixes, then mapping non-ASCII digits into ASCII
1872     * digits via {@link Character#digit Character.digit}, prepending a
1873     * negative sign (-) if the locale specific negative prefixes and suffixes
1874     * were present, and passing the resulting string to
1875     * {@link Byte#parseByte(String, int) Byte.parseByte} with the
1876     * specified radix.
1877     *
1878     * @param radix the radix used to interpret the token as a byte value
1879     * @return the <tt>byte</tt> scanned from the input
1880     * @throws InputMismatchException
1881     *         if the next token does not match the <i>Integer</i>
1882     *         regular expression, or is out of range
1883     * @throws NoSuchElementException if input is exhausted
1884     * @throws IllegalStateException if this scanner is closed
1885     */
1886    public byte nextByte(int radix) {
1887        // Check cached result
1888        if ((typeCache != null) && (typeCache instanceof Byte)
1889            && this.radix == radix) {
1890            byte val = ((Byte)typeCache).byteValue();
1891            useTypeCache();
1892            return val;
1893        }
1894        setRadix(radix);
1895        clearCaches();
1896        // Search for next byte
1897        try {
1898            String s = next(integerPattern());
1899            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
1900                s = processIntegerToken(s);
1901            return Byte.parseByte(s, radix);
1902        } catch (NumberFormatException nfe) {
1903            position = matcher.start(); // don't skip bad token
1904            throw new InputMismatchException(nfe.getMessage());
1905        }
1906    }
1907
1908    /**
1909     * Returns true if the next token in this scanner's input can be
1910     * interpreted as a short value in the default radix using the
1911     * {@link #nextShort} method. The scanner does not advance past any input.
1912     *
1913     * @return true if and only if this scanner's next token is a valid
1914     *         short value in the default radix
1915     * @throws IllegalStateException if this scanner is closed
1916     */
1917    public boolean hasNextShort() {
1918        return hasNextShort(defaultRadix);
1919    }
1920
1921    /**
1922     * Returns true if the next token in this scanner's input can be
1923     * interpreted as a short value in the specified radix using the
1924     * {@link #nextShort} method. The scanner does not advance past any input.
1925     *
1926     * @param radix the radix used to interpret the token as a short value
1927     * @return true if and only if this scanner's next token is a valid
1928     *         short value in the specified radix
1929     * @throws IllegalStateException if this scanner is closed
1930     */
1931    public boolean hasNextShort(int radix) {
1932        setRadix(radix);
1933        boolean result = hasNext(integerPattern());
1934        if (result) { // Cache it
1935            try {
1936                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1937                    processIntegerToken(hasNextResult) :
1938                    hasNextResult;
1939                typeCache = Short.parseShort(s, radix);
1940            } catch (NumberFormatException nfe) {
1941                result = false;
1942            }
1943        }
1944        return result;
1945    }
1946
1947    /**
1948     * Scans the next token of the input as a <tt>short</tt>.
1949     *
1950     * <p> An invocation of this method of the form
1951     * <tt>nextShort()</tt> behaves in exactly the same way as the
1952     * invocation <tt>nextShort(radix)</tt>, where <code>radix</code>
1953     * is the default radix of this scanner.
1954     *
1955     * @return the <tt>short</tt> scanned from the input
1956     * @throws InputMismatchException
1957     *         if the next token does not match the <i>Integer</i>
1958     *         regular expression, or is out of range
1959     * @throws NoSuchElementException if input is exhausted
1960     * @throws IllegalStateException if this scanner is closed
1961     */
1962    public short nextShort() {
1963        return nextShort(defaultRadix);
1964    }
1965
1966    /**
1967     * Scans the next token of the input as a <tt>short</tt>.
1968     * This method will throw <code>InputMismatchException</code>
1969     * if the next token cannot be translated into a valid short value as
1970     * described below. If the translation is successful, the scanner advances
1971     * past the input that matched.
1972     *
1973     * <p> If the next token matches the <a
1974     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
1975     * above then the token is converted into a <tt>short</tt> value as if by
1976     * removing all locale specific prefixes, group separators, and locale
1977     * specific suffixes, then mapping non-ASCII digits into ASCII
1978     * digits via {@link Character#digit Character.digit}, prepending a
1979     * negative sign (-) if the locale specific negative prefixes and suffixes
1980     * were present, and passing the resulting string to
1981     * {@link Short#parseShort(String, int) Short.parseShort} with the
1982     * specified radix.
1983     *
1984     * @param radix the radix used to interpret the token as a short value
1985     * @return the <tt>short</tt> scanned from the input
1986     * @throws InputMismatchException
1987     *         if the next token does not match the <i>Integer</i>
1988     *         regular expression, or is out of range
1989     * @throws NoSuchElementException if input is exhausted
1990     * @throws IllegalStateException if this scanner is closed
1991     */
1992    public short nextShort(int radix) {
1993        // Check cached result
1994        if ((typeCache != null) && (typeCache instanceof Short)
1995            && this.radix == radix) {
1996            short val = ((Short)typeCache).shortValue();
1997            useTypeCache();
1998            return val;
1999        }
2000        setRadix(radix);
2001        clearCaches();
2002        // Search for next short
2003        try {
2004            String s = next(integerPattern());
2005            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2006                s = processIntegerToken(s);
2007            return Short.parseShort(s, radix);
2008        } catch (NumberFormatException nfe) {
2009            position = matcher.start(); // don't skip bad token
2010            throw new InputMismatchException(nfe.getMessage());
2011        }
2012    }
2013
2014    /**
2015     * Returns true if the next token in this scanner's input can be
2016     * interpreted as an int value in the default radix using the
2017     * {@link #nextInt} method. The scanner does not advance past any input.
2018     *
2019     * @return true if and only if this scanner's next token is a valid
2020     *         int value
2021     * @throws IllegalStateException if this scanner is closed
2022     */
2023    public boolean hasNextInt() {
2024        return hasNextInt(defaultRadix);
2025    }
2026
2027    /**
2028     * Returns true if the next token in this scanner's input can be
2029     * interpreted as an int value in the specified radix using the
2030     * {@link #nextInt} method. The scanner does not advance past any input.
2031     *
2032     * @param radix the radix used to interpret the token as an int value
2033     * @return true if and only if this scanner's next token is a valid
2034     *         int value
2035     * @throws IllegalStateException if this scanner is closed
2036     */
2037    public boolean hasNextInt(int radix) {
2038        setRadix(radix);
2039        boolean result = hasNext(integerPattern());
2040        if (result) { // Cache it
2041            try {
2042                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2043                    processIntegerToken(hasNextResult) :
2044                    hasNextResult;
2045                typeCache = Integer.parseInt(s, radix);
2046            } catch (NumberFormatException nfe) {
2047                result = false;
2048            }
2049        }
2050        return result;
2051    }
2052
2053    /**
2054     * The integer token must be stripped of prefixes, group separators,
2055     * and suffixes, non ascii digits must be converted into ascii digits
2056     * before parse will accept it.
2057     */
2058    private String processIntegerToken(String token) {
2059        String result = token.replaceAll(""+groupSeparator, "");
2060        boolean isNegative = false;
2061        int preLen = negativePrefix.length();
2062        if ((preLen > 0) && result.startsWith(negativePrefix)) {
2063            isNegative = true;
2064            result = result.substring(preLen);
2065        }
2066        int sufLen = negativeSuffix.length();
2067        if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2068            isNegative = true;
2069            result = result.substring(result.length() - sufLen,
2070                                      result.length());
2071        }
2072        if (isNegative)
2073            result = "-" + result;
2074        return result;
2075    }
2076
2077    /**
2078     * Scans the next token of the input as an <tt>int</tt>.
2079     *
2080     * <p> An invocation of this method of the form
2081     * <tt>nextInt()</tt> behaves in exactly the same way as the
2082     * invocation <tt>nextInt(radix)</tt>, where <code>radix</code>
2083     * is the default radix of this scanner.
2084     *
2085     * @return the <tt>int</tt> scanned from the input
2086     * @throws InputMismatchException
2087     *         if the next token does not match the <i>Integer</i>
2088     *         regular expression, or is out of range
2089     * @throws NoSuchElementException if input is exhausted
2090     * @throws IllegalStateException if this scanner is closed
2091     */
2092    public int nextInt() {
2093        return nextInt(defaultRadix);
2094    }
2095
2096    /**
2097     * Scans the next token of the input as an <tt>int</tt>.
2098     * This method will throw <code>InputMismatchException</code>
2099     * if the next token cannot be translated into a valid int value as
2100     * described below. If the translation is successful, the scanner advances
2101     * past the input that matched.
2102     *
2103     * <p> If the next token matches the <a
2104     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2105     * above then the token is converted into an <tt>int</tt> value as if by
2106     * removing all locale specific prefixes, group separators, and locale
2107     * specific suffixes, then mapping non-ASCII digits into ASCII
2108     * digits via {@link Character#digit Character.digit}, prepending a
2109     * negative sign (-) if the locale specific negative prefixes and suffixes
2110     * were present, and passing the resulting string to
2111     * {@link Integer#parseInt(String, int) Integer.parseInt} with the
2112     * specified radix.
2113     *
2114     * @param radix the radix used to interpret the token as an int value
2115     * @return the <tt>int</tt> scanned from the input
2116     * @throws InputMismatchException
2117     *         if the next token does not match the <i>Integer</i>
2118     *         regular expression, or is out of range
2119     * @throws NoSuchElementException if input is exhausted
2120     * @throws IllegalStateException if this scanner is closed
2121     */
2122    public int nextInt(int radix) {
2123        // Check cached result
2124        if ((typeCache != null) && (typeCache instanceof Integer)
2125            && this.radix == radix) {
2126            int val = ((Integer)typeCache).intValue();
2127            useTypeCache();
2128            return val;
2129        }
2130        setRadix(radix);
2131        clearCaches();
2132        // Search for next int
2133        try {
2134            String s = next(integerPattern());
2135            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2136                s = processIntegerToken(s);
2137            return Integer.parseInt(s, radix);
2138        } catch (NumberFormatException nfe) {
2139            position = matcher.start(); // don't skip bad token
2140            throw new InputMismatchException(nfe.getMessage());
2141        }
2142    }
2143
2144    /**
2145     * Returns true if the next token in this scanner's input can be
2146     * interpreted as a long value in the default radix using the
2147     * {@link #nextLong} method. The scanner does not advance past any input.
2148     *
2149     * @return true if and only if this scanner's next token is a valid
2150     *         long value
2151     * @throws IllegalStateException if this scanner is closed
2152     */
2153    public boolean hasNextLong() {
2154        return hasNextLong(defaultRadix);
2155    }
2156
2157    /**
2158     * Returns true if the next token in this scanner's input can be
2159     * interpreted as a long value in the specified radix using the
2160     * {@link #nextLong} method. The scanner does not advance past any input.
2161     *
2162     * @param radix the radix used to interpret the token as a long value
2163     * @return true if and only if this scanner's next token is a valid
2164     *         long value
2165     * @throws IllegalStateException if this scanner is closed
2166     */
2167    public boolean hasNextLong(int radix) {
2168        setRadix(radix);
2169        boolean result = hasNext(integerPattern());
2170        if (result) { // Cache it
2171            try {
2172                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2173                    processIntegerToken(hasNextResult) :
2174                    hasNextResult;
2175                typeCache = Long.parseLong(s, radix);
2176            } catch (NumberFormatException nfe) {
2177                result = false;
2178            }
2179        }
2180        return result;
2181    }
2182
2183    /**
2184     * Scans the next token of the input as a <tt>long</tt>.
2185     *
2186     * <p> An invocation of this method of the form
2187     * <tt>nextLong()</tt> behaves in exactly the same way as the
2188     * invocation <tt>nextLong(radix)</tt>, where <code>radix</code>
2189     * is the default radix of this scanner.
2190     *
2191     * @return the <tt>long</tt> scanned from the input
2192     * @throws InputMismatchException
2193     *         if the next token does not match the <i>Integer</i>
2194     *         regular expression, or is out of range
2195     * @throws NoSuchElementException if input is exhausted
2196     * @throws IllegalStateException if this scanner is closed
2197     */
2198    public long nextLong() {
2199        return nextLong(defaultRadix);
2200    }
2201
2202    /**
2203     * Scans the next token of the input as a <tt>long</tt>.
2204     * This method will throw <code>InputMismatchException</code>
2205     * if the next token cannot be translated into a valid long value as
2206     * described below. If the translation is successful, the scanner advances
2207     * past the input that matched.
2208     *
2209     * <p> If the next token matches the <a
2210     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2211     * above then the token is converted into a <tt>long</tt> value as if by
2212     * removing all locale specific prefixes, group separators, and locale
2213     * specific suffixes, then mapping non-ASCII digits into ASCII
2214     * digits via {@link Character#digit Character.digit}, prepending a
2215     * negative sign (-) if the locale specific negative prefixes and suffixes
2216     * were present, and passing the resulting string to
2217     * {@link Long#parseLong(String, int) Long.parseLong} with the
2218     * specified radix.
2219     *
2220     * @param radix the radix used to interpret the token as an int value
2221     * @return the <tt>long</tt> scanned from the input
2222     * @throws InputMismatchException
2223     *         if the next token does not match the <i>Integer</i>
2224     *         regular expression, or is out of range
2225     * @throws NoSuchElementException if input is exhausted
2226     * @throws IllegalStateException if this scanner is closed
2227     */
2228    public long nextLong(int radix) {
2229        // Check cached result
2230        if ((typeCache != null) && (typeCache instanceof Long)
2231            && this.radix == radix) {
2232            long val = ((Long)typeCache).longValue();
2233            useTypeCache();
2234            return val;
2235        }
2236        setRadix(radix);
2237        clearCaches();
2238        try {
2239            String s = next(integerPattern());
2240            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2241                s = processIntegerToken(s);
2242            return Long.parseLong(s, radix);
2243        } catch (NumberFormatException nfe) {
2244            position = matcher.start(); // don't skip bad token
2245            throw new InputMismatchException(nfe.getMessage());
2246        }
2247    }
2248
2249    /**
2250     * The float token must be stripped of prefixes, group separators,
2251     * and suffixes, non ascii digits must be converted into ascii digits
2252     * before parseFloat will accept it.
2253     *
2254     * If there are non-ascii digits in the token these digits must
2255     * be processed before the token is passed to parseFloat.
2256     */
2257    private String processFloatToken(String token) {
2258        String result = token.replaceAll(groupSeparator, "");
2259        if (!decimalSeparator.equals("\\."))
2260            result = result.replaceAll(decimalSeparator, ".");
2261        boolean isNegative = false;
2262        int preLen = negativePrefix.length();
2263        if ((preLen > 0) && result.startsWith(negativePrefix)) {
2264            isNegative = true;
2265            result = result.substring(preLen);
2266        }
2267        int sufLen = negativeSuffix.length();
2268        if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2269            isNegative = true;
2270            result = result.substring(result.length() - sufLen,
2271                                      result.length());
2272        }
2273        if (result.equals(nanString))
2274            result = "NaN";
2275        if (result.equals(infinityString))
2276            result = "Infinity";
2277        // Android-changed: Match the infinity symbol.
2278        if (result.equals("\u221E"))
2279            result = "Infinity";
2280        if (isNegative)
2281            result = "-" + result;
2282
2283        // Translate non-ASCII digits
2284        Matcher m = NON_ASCII_DIGIT.matcher(result);
2285        if (m.find()) {
2286            StringBuilder inASCII = new StringBuilder();
2287            for (int i=0; i<result.length(); i++) {
2288                char nextChar = result.charAt(i);
2289                if (Character.isDigit(nextChar)) {
2290                    int d = Character.digit(nextChar, 10);
2291                    if (d != -1)
2292                        inASCII.append(d);
2293                    else
2294                        inASCII.append(nextChar);
2295                } else {
2296                    inASCII.append(nextChar);
2297                }
2298            }
2299            result = inASCII.toString();
2300        }
2301
2302        return result;
2303    }
2304
2305    /**
2306     * Returns true if the next token in this scanner's input can be
2307     * interpreted as a float value using the {@link #nextFloat}
2308     * method. The scanner does not advance past any input.
2309     *
2310     * @return true if and only if this scanner's next token is a valid
2311     *         float value
2312     * @throws IllegalStateException if this scanner is closed
2313     */
2314    public boolean hasNextFloat() {
2315        setRadix(10);
2316        boolean result = hasNext(floatPattern());
2317        if (result) { // Cache it
2318            try {
2319                String s = processFloatToken(hasNextResult);
2320                typeCache = Float.valueOf(Float.parseFloat(s));
2321            } catch (NumberFormatException nfe) {
2322                result = false;
2323            }
2324        }
2325        return result;
2326    }
2327
2328    /**
2329     * Scans the next token of the input as a <tt>float</tt>.
2330     * This method will throw <code>InputMismatchException</code>
2331     * if the next token cannot be translated into a valid float value as
2332     * described below. If the translation is successful, the scanner advances
2333     * past the input that matched.
2334     *
2335     * <p> If the next token matches the <a
2336     * href="#Float-regex"><i>Float</i></a> regular expression defined above
2337     * then the token is converted into a <tt>float</tt> value as if by
2338     * removing all locale specific prefixes, group separators, and locale
2339     * specific suffixes, then mapping non-ASCII digits into ASCII
2340     * digits via {@link Character#digit Character.digit}, prepending a
2341     * negative sign (-) if the locale specific negative prefixes and suffixes
2342     * were present, and passing the resulting string to
2343     * {@link Float#parseFloat Float.parseFloat}. If the token matches
2344     * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2345     * is passed to {@link Float#parseFloat(String) Float.parseFloat} as
2346     * appropriate.
2347     *
2348     * @return the <tt>float</tt> scanned from the input
2349     * @throws InputMismatchException
2350     *         if the next token does not match the <i>Float</i>
2351     *         regular expression, or is out of range
2352     * @throws NoSuchElementException if input is exhausted
2353     * @throws IllegalStateException if this scanner is closed
2354     */
2355    public float nextFloat() {
2356        // Check cached result
2357        if ((typeCache != null) && (typeCache instanceof Float)) {
2358            float val = ((Float)typeCache).floatValue();
2359            useTypeCache();
2360            return val;
2361        }
2362        setRadix(10);
2363        clearCaches();
2364        try {
2365            return Float.parseFloat(processFloatToken(next(floatPattern())));
2366        } catch (NumberFormatException nfe) {
2367            position = matcher.start(); // don't skip bad token
2368            throw new InputMismatchException(nfe.getMessage());
2369        }
2370    }
2371
2372    /**
2373     * Returns true if the next token in this scanner's input can be
2374     * interpreted as a double value using the {@link #nextDouble}
2375     * method. The scanner does not advance past any input.
2376     *
2377     * @return true if and only if this scanner's next token is a valid
2378     *         double value
2379     * @throws IllegalStateException if this scanner is closed
2380     */
2381    public boolean hasNextDouble() {
2382        setRadix(10);
2383        boolean result = hasNext(floatPattern());
2384        if (result) { // Cache it
2385            try {
2386                String s = processFloatToken(hasNextResult);
2387                typeCache = Double.valueOf(Double.parseDouble(s));
2388            } catch (NumberFormatException nfe) {
2389                result = false;
2390            }
2391        }
2392        return result;
2393    }
2394
2395    /**
2396     * Scans the next token of the input as a <tt>double</tt>.
2397     * This method will throw <code>InputMismatchException</code>
2398     * if the next token cannot be translated into a valid double value.
2399     * If the translation is successful, the scanner advances past the input
2400     * that matched.
2401     *
2402     * <p> If the next token matches the <a
2403     * href="#Float-regex"><i>Float</i></a> regular expression defined above
2404     * then the token is converted into a <tt>double</tt> value as if by
2405     * removing all locale specific prefixes, group separators, and locale
2406     * specific suffixes, then mapping non-ASCII digits into ASCII
2407     * digits via {@link Character#digit Character.digit}, prepending a
2408     * negative sign (-) if the locale specific negative prefixes and suffixes
2409     * were present, and passing the resulting string to
2410     * {@link Double#parseDouble Double.parseDouble}. If the token matches
2411     * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2412     * is passed to {@link Double#parseDouble(String) Double.parseDouble} as
2413     * appropriate.
2414     *
2415     * @return the <tt>double</tt> scanned from the input
2416     * @throws InputMismatchException
2417     *         if the next token does not match the <i>Float</i>
2418     *         regular expression, or is out of range
2419     * @throws NoSuchElementException if the input is exhausted
2420     * @throws IllegalStateException if this scanner is closed
2421     */
2422    public double nextDouble() {
2423        // Check cached result
2424        if ((typeCache != null) && (typeCache instanceof Double)) {
2425            double val = ((Double)typeCache).doubleValue();
2426            useTypeCache();
2427            return val;
2428        }
2429        setRadix(10);
2430        clearCaches();
2431        // Search for next float
2432        try {
2433            return Double.parseDouble(processFloatToken(next(floatPattern())));
2434        } catch (NumberFormatException nfe) {
2435            position = matcher.start(); // don't skip bad token
2436            throw new InputMismatchException(nfe.getMessage());
2437        }
2438    }
2439
2440    // Convenience methods for scanning multi precision numbers
2441
2442    /**
2443     * Returns true if the next token in this scanner's input can be
2444     * interpreted as a <code>BigInteger</code> in the default radix using the
2445     * {@link #nextBigInteger} method. The scanner does not advance past any
2446     * input.
2447     *
2448     * @return true if and only if this scanner's next token is a valid
2449     *         <code>BigInteger</code>
2450     * @throws IllegalStateException if this scanner is closed
2451     */
2452    public boolean hasNextBigInteger() {
2453        return hasNextBigInteger(defaultRadix);
2454    }
2455
2456    /**
2457     * Returns true if the next token in this scanner's input can be
2458     * interpreted as a <code>BigInteger</code> in the specified radix using
2459     * the {@link #nextBigInteger} method. The scanner does not advance past
2460     * any input.
2461     *
2462     * @param radix the radix used to interpret the token as an integer
2463     * @return true if and only if this scanner's next token is a valid
2464     *         <code>BigInteger</code>
2465     * @throws IllegalStateException if this scanner is closed
2466     */
2467    public boolean hasNextBigInteger(int radix) {
2468        setRadix(radix);
2469        boolean result = hasNext(integerPattern());
2470        if (result) { // Cache it
2471            try {
2472                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2473                    processIntegerToken(hasNextResult) :
2474                    hasNextResult;
2475                typeCache = new BigInteger(s, radix);
2476            } catch (NumberFormatException nfe) {
2477                result = false;
2478            }
2479        }
2480        return result;
2481    }
2482
2483    /**
2484     * Scans the next token of the input as a {@link java.math.BigInteger
2485     * BigInteger}.
2486     *
2487     * <p> An invocation of this method of the form
2488     * <tt>nextBigInteger()</tt> behaves in exactly the same way as the
2489     * invocation <tt>nextBigInteger(radix)</tt>, where <code>radix</code>
2490     * is the default radix of this scanner.
2491     *
2492     * @return the <tt>BigInteger</tt> scanned from the input
2493     * @throws InputMismatchException
2494     *         if the next token does not match the <i>Integer</i>
2495     *         regular expression, or is out of range
2496     * @throws NoSuchElementException if the input is exhausted
2497     * @throws IllegalStateException if this scanner is closed
2498     */
2499    public BigInteger nextBigInteger() {
2500        return nextBigInteger(defaultRadix);
2501    }
2502
2503    /**
2504     * Scans the next token of the input as a {@link java.math.BigInteger
2505     * BigInteger}.
2506     *
2507     * <p> If the next token matches the <a
2508     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2509     * above then the token is converted into a <tt>BigInteger</tt> value as if
2510     * by removing all group separators, mapping non-ASCII digits into ASCII
2511     * digits via the {@link Character#digit Character.digit}, and passing the
2512     * resulting string to the {@link
2513     * java.math.BigInteger#BigInteger(java.lang.String)
2514     * BigInteger(String, int)} constructor with the specified radix.
2515     *
2516     * @param radix the radix used to interpret the token
2517     * @return the <tt>BigInteger</tt> scanned from the input
2518     * @throws InputMismatchException
2519     *         if the next token does not match the <i>Integer</i>
2520     *         regular expression, or is out of range
2521     * @throws NoSuchElementException if the input is exhausted
2522     * @throws IllegalStateException if this scanner is closed
2523     */
2524    public BigInteger nextBigInteger(int radix) {
2525        // Check cached result
2526        if ((typeCache != null) && (typeCache instanceof BigInteger)
2527            && this.radix == radix) {
2528            BigInteger val = (BigInteger)typeCache;
2529            useTypeCache();
2530            return val;
2531        }
2532        setRadix(radix);
2533        clearCaches();
2534        // Search for next int
2535        try {
2536            String s = next(integerPattern());
2537            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2538                s = processIntegerToken(s);
2539            return new BigInteger(s, radix);
2540        } catch (NumberFormatException nfe) {
2541            position = matcher.start(); // don't skip bad token
2542            throw new InputMismatchException(nfe.getMessage());
2543        }
2544    }
2545
2546    /**
2547     * Returns true if the next token in this scanner's input can be
2548     * interpreted as a <code>BigDecimal</code> using the
2549     * {@link #nextBigDecimal} method. The scanner does not advance past any
2550     * input.
2551     *
2552     * @return true if and only if this scanner's next token is a valid
2553     *         <code>BigDecimal</code>
2554     * @throws IllegalStateException if this scanner is closed
2555     */
2556    public boolean hasNextBigDecimal() {
2557        setRadix(10);
2558        boolean result = hasNext(decimalPattern());
2559        if (result) { // Cache it
2560            try {
2561                String s = processFloatToken(hasNextResult);
2562                typeCache = new BigDecimal(s);
2563            } catch (NumberFormatException nfe) {
2564                result = false;
2565            }
2566        }
2567        return result;
2568    }
2569
2570    /**
2571     * Scans the next token of the input as a {@link java.math.BigDecimal
2572     * BigDecimal}.
2573     *
2574     * <p> If the next token matches the <a
2575     * href="#Decimal-regex"><i>Decimal</i></a> regular expression defined
2576     * above then the token is converted into a <tt>BigDecimal</tt> value as if
2577     * by removing all group separators, mapping non-ASCII digits into ASCII
2578     * digits via the {@link Character#digit Character.digit}, and passing the
2579     * resulting string to the {@link
2580     * java.math.BigDecimal#BigDecimal(java.lang.String) BigDecimal(String)}
2581     * constructor.
2582     *
2583     * @return the <tt>BigDecimal</tt> scanned from the input
2584     * @throws InputMismatchException
2585     *         if the next token does not match the <i>Decimal</i>
2586     *         regular expression, or is out of range
2587     * @throws NoSuchElementException if the input is exhausted
2588     * @throws IllegalStateException if this scanner is closed
2589     */
2590    public BigDecimal nextBigDecimal() {
2591        // Check cached result
2592        if ((typeCache != null) && (typeCache instanceof BigDecimal)) {
2593            BigDecimal val = (BigDecimal)typeCache;
2594            useTypeCache();
2595            return val;
2596        }
2597        setRadix(10);
2598        clearCaches();
2599        // Search for next float
2600        try {
2601            String s = processFloatToken(next(decimalPattern()));
2602            return new BigDecimal(s);
2603        } catch (NumberFormatException nfe) {
2604            position = matcher.start(); // don't skip bad token
2605            throw new InputMismatchException(nfe.getMessage());
2606        }
2607    }
2608
2609    /**
2610     * Resets this scanner.
2611     *
2612     * <p> Resetting a scanner discards all of its explicit state
2613     * information which may have been changed by invocations of {@link
2614     * #useDelimiter}, {@link #useLocale}, or {@link #useRadix}.
2615     *
2616     * <p> An invocation of this method of the form
2617     * <tt>scanner.reset()</tt> behaves in exactly the same way as the
2618     * invocation
2619     *
2620     * <blockquote><pre>{@code
2621     *   scanner.useDelimiter("\\p{javaWhitespace}+")
2622     *          .useLocale(Locale.getDefault(Locale.Category.FORMAT))
2623     *          .useRadix(10);
2624     * }</pre></blockquote>
2625     *
2626     * @return this scanner
2627     *
2628     * @since 1.6
2629     */
2630    public Scanner reset() {
2631        delimPattern = WHITESPACE_PATTERN;
2632        useLocale(Locale.getDefault(Locale.Category.FORMAT));
2633        useRadix(10);
2634        clearCaches();
2635        return this;
2636    }
2637}
2638