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