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