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