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