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