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