21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.*;
29 import java.math.*;
30 import java.nio.*;
31 import java.nio.channels.*;
32 import java.nio.charset.*;
33 import java.nio.file.Path;
34 import java.nio.file.Files;
35 import java.text.*;
36 import java.util.function.Consumer;
37 import java.util.regex.*;
38 import java.util.stream.Stream;
39 import java.util.stream.StreamSupport;
40
41 import sun.misc.LRUCache;
42
43 /**
44 * A simple text scanner which can parse primitive types and strings using
45 * regular expressions.
46 *
47 * <p>A {@code Scanner} breaks its input into tokens using a
48 * delimiter pattern, which by default matches whitespace. The resulting
49 * tokens may then be converted into values of different types using the
50 * various {@code next} methods.
51 *
52 * <p>For example, this code allows a user to read a number from
53 * {@code System.in}:
54 * <blockquote><pre>{@code
55 * Scanner sc = new Scanner(System.in);
56 * int i = sc.nextInt();
57 * }</pre></blockquote>
58 *
59 * <p>As another example, this code allows {@code long} types to be
60 * assigned from entries in a file {@code myNumbers}:
61 * <blockquote><pre>{@code
62 * Scanner sc = new Scanner(new File("myNumbers"));
349
350 // A cache of the last primitive type scanned
351 private Object typeCache = null;
352
353 // Boolean indicating if a match result is available
354 private boolean matchValid = false;
355
356 // Boolean indicating if this scanner has been closed
357 private boolean closed = false;
358
359 // The current radix used by this scanner
360 private int radix = 10;
361
362 // The default radix for this scanner
363 private int defaultRadix = 10;
364
365 // The locale used by this scanner
366 private Locale locale = null;
367
368 // A cache of the last few recently used Patterns
369 private LRUCache<String,Pattern> patternCache =
370 new LRUCache<String,Pattern>(7) {
371 protected Pattern create(String s) {
372 return Pattern.compile(s);
373 }
374 protected boolean hasName(Pattern p, String s) {
375 return p.pattern().equals(s);
376 }
377 };
378
379 // A holder of the last IOException encountered
380 private IOException lastException;
381
382 // Number of times this scanner's state has been modified.
383 // Generally incremented on most public APIs and checked
384 // within spliterator implementations.
385 int modCount;
386
387 // A pattern for java whitespace
388 private static Pattern WHITESPACE_PATTERN = Pattern.compile(
389 "\\p{javaWhitespace}+");
390
391 // A pattern for any token
392 private static Pattern FIND_ANY_PATTERN = Pattern.compile("(?s).*");
393
394 // A pattern for non-ASCII digits
395 private static Pattern NON_ASCII_DIGIT = Pattern.compile(
396 "[\\p{javaDigit}&&[^0-9]]");
397
2819 throw new ConcurrentModificationException();
2820 }
2821 } else {
2822 expectedCount = modCount;
2823 }
2824
2825 while (true) {
2826 // assert expectedCount == modCount
2827 if (findPatternInBuffer(pattern, 0)) { // doesn't increment modCount
2828 cons.accept(matcher.toMatchResult());
2829 if (expectedCount != modCount) {
2830 throw new ConcurrentModificationException();
2831 }
2832 return true;
2833 }
2834 if (needInput)
2835 readInput(); // doesn't increment modCount
2836 else
2837 return false; // reached end of input
2838 }
2839 }
2840 }
2841 }
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.*;
29 import java.math.*;
30 import java.nio.*;
31 import java.nio.channels.*;
32 import java.nio.charset.*;
33 import java.nio.file.Path;
34 import java.nio.file.Files;
35 import java.text.*;
36 import java.util.function.Consumer;
37 import java.util.regex.*;
38 import java.util.stream.Stream;
39 import java.util.stream.StreamSupport;
40
41 /**
42 * A simple text scanner which can parse primitive types and strings using
43 * regular expressions.
44 *
45 * <p>A {@code Scanner} breaks its input into tokens using a
46 * delimiter pattern, which by default matches whitespace. The resulting
47 * tokens may then be converted into values of different types using the
48 * various {@code next} methods.
49 *
50 * <p>For example, this code allows a user to read a number from
51 * {@code System.in}:
52 * <blockquote><pre>{@code
53 * Scanner sc = new Scanner(System.in);
54 * int i = sc.nextInt();
55 * }</pre></blockquote>
56 *
57 * <p>As another example, this code allows {@code long} types to be
58 * assigned from entries in a file {@code myNumbers}:
59 * <blockquote><pre>{@code
60 * Scanner sc = new Scanner(new File("myNumbers"));
347
348 // A cache of the last primitive type scanned
349 private Object typeCache = null;
350
351 // Boolean indicating if a match result is available
352 private boolean matchValid = false;
353
354 // Boolean indicating if this scanner has been closed
355 private boolean closed = false;
356
357 // The current radix used by this scanner
358 private int radix = 10;
359
360 // The default radix for this scanner
361 private int defaultRadix = 10;
362
363 // The locale used by this scanner
364 private Locale locale = null;
365
366 // A cache of the last few recently used Patterns
367 private PatternLRUCache patternCache = new PatternLRUCache(7);
368
369 // A holder of the last IOException encountered
370 private IOException lastException;
371
372 // Number of times this scanner's state has been modified.
373 // Generally incremented on most public APIs and checked
374 // within spliterator implementations.
375 int modCount;
376
377 // A pattern for java whitespace
378 private static Pattern WHITESPACE_PATTERN = Pattern.compile(
379 "\\p{javaWhitespace}+");
380
381 // A pattern for any token
382 private static Pattern FIND_ANY_PATTERN = Pattern.compile("(?s).*");
383
384 // A pattern for non-ASCII digits
385 private static Pattern NON_ASCII_DIGIT = Pattern.compile(
386 "[\\p{javaDigit}&&[^0-9]]");
387
2809 throw new ConcurrentModificationException();
2810 }
2811 } else {
2812 expectedCount = modCount;
2813 }
2814
2815 while (true) {
2816 // assert expectedCount == modCount
2817 if (findPatternInBuffer(pattern, 0)) { // doesn't increment modCount
2818 cons.accept(matcher.toMatchResult());
2819 if (expectedCount != modCount) {
2820 throw new ConcurrentModificationException();
2821 }
2822 return true;
2823 }
2824 if (needInput)
2825 readInput(); // doesn't increment modCount
2826 else
2827 return false; // reached end of input
2828 }
2829 }
2830 }
2831
2832 /** Utility class for small LRU caches. */
2833 private static class PatternLRUCache {
2834
2835 private Pattern[] oa = null;
2836 private final int size;
2837
2838 PatternLRUCache(int size) {
2839 this.size = size;
2840 }
2841
2842 boolean hasName(Pattern p, String s) {
2843 return p.pattern().equals(s);
2844 }
2845
2846 void moveToFront(Object[] oa, int i) {
2847 Object ob = oa[i];
2848 for (int j = i; j > 0; j--)
2849 oa[j] = oa[j - 1];
2850 oa[0] = ob;
2851 }
2852
2853 Pattern forName(String name) {
2854 if (oa == null) {
2855 Pattern[] temp = new Pattern[size];
2856 oa = temp;
2857 } else {
2858 for (int i = 0; i < oa.length; i++) {
2859 Pattern ob = oa[i];
2860 if (ob == null)
2861 continue;
2862 if (hasName(ob, name)) {
2863 if (i > 0)
2864 moveToFront(oa, i);
2865 return ob;
2866 }
2867 }
2868 }
2869
2870 // Create a new object
2871 Pattern ob = Pattern.compile(name);
2872 oa[oa.length - 1] = ob;
2873 moveToFront(oa, oa.length - 1);
2874 return ob;
2875 }
2876 }
2877 }
|