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