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