1 7 8 package java.util; 9 10 import java.util.regex.*; 11 import java.io.*; 12 import java.math.*; 13 import java.nio.*; 14 import java.nio.channels.*; 15 import java.nio.charset.*; 16 import java.text.*; 17 import java.util.Locale ; 18 import sun.io.Converters; 19 import sun.misc.LRUCache; 20 21 323 public final class Scanner implements Iterator <String > { 324 325 private CharBuffer buf; 327 328 private static final int BUFFER_SIZE = 1024; 331 private int position; 333 334 private Matcher matcher; 336 337 private Pattern delimPattern; 339 340 private Pattern hasNextPattern; 342 343 private int hasNextPosition; 345 346 private String hasNextResult; 348 349 private Readable source; 351 352 private boolean sourceClosed = false; 354 355 private boolean needInput = false; 357 358 private boolean skipped = false; 360 361 private int savedScannerPosition = -1; 363 364 private Object typeCache = null; 366 367 private boolean matchValid = false; 369 370 private boolean closed = false; 372 373 private int radix = 10; 375 376 private int defaultRadix = 10; 378 379 private Locale locale = null; 381 382 private LRUCache<String ,Pattern> patternCache = 384 new LRUCache<String ,Pattern>(7) { 385 protected Pattern create(String s) { 386 return Pattern.compile(s); 387 } 388 protected boolean hasName(Pattern p, String s) { 389 return p.pattern().equals(s); 390 } 391 }; 392 393 private IOException lastException; 395 396 private static Pattern WHITESPACE_PATTERN = Pattern.compile( 398 "\\p{javaWhitespace}+"); 399 400 private static Pattern FIND_ANY_PATTERN = Pattern.compile("(?s).*"); 402 403 private static Pattern NON_ASCII_DIGIT = Pattern.compile( 405 "[\\p{javaDigit}&&[^0-9]]"); 406 407 409 412 private String groupSeparator = "\\,"; 413 private String decimalSeparator = "\\."; 414 private String nanString = "NaN"; 415 private String infinityString = "Infinity"; 416 private String positivePrefix = ""; 417 private String negativePrefix = "\\-"; 418 private String positiveSuffix = ""; 419 private String negativeSuffix = ""; 420 421 424 private static volatile Pattern boolPattern; 425 private static final String BOOLEAN_PATTERN = "true|false"; 426 private static Pattern boolPattern() { 427 Pattern bp = boolPattern; 428 if (bp == null) 429 boolPattern = bp = Pattern.compile(BOOLEAN_PATTERN, 430 Pattern.CASE_INSENSITIVE); 431 return bp; 432 } 433 434 437 private Pattern integerPattern; 438 private String digits = "0123456789abcdefghijklmnopqrstuvwxyz"; 439 private String non0Digit = "[\\p{javaDigit}&&[^0]]"; 440 private int SIMPLE_GROUP_INDEX = 5; 441 private String buildIntegerPatternString() { 442 String radixDigits = digits.substring(0, radix); 443 String digit = "((?i)["+radixDigits+"]|\\p{javaDigit})"; 448 String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+ 449 groupSeparator+digit+digit+digit+")+)"; 450 String numeral = "(("+ digit+"++)|"+groupedNumeral+")"; 453 String javaStyleInteger = "([-+]?(" + numeral + "))"; 454 String negativeInteger = negativePrefix + numeral + negativeSuffix; 455 String positiveInteger = positivePrefix + numeral + positiveSuffix; 456 return "("+ javaStyleInteger + ")|(" + 457 positiveInteger + ")|(" + 458 negativeInteger + ")"; 459 } 460 private Pattern integerPattern() { 461 if (integerPattern == null) { 462 integerPattern = patternCache.forName(buildIntegerPatternString()); 463 } 464 return integerPattern; 465 } 466 467 470 private static volatile Pattern separatorPattern; 471 private static final String LINE_SEPARATOR_PATTERN = 472 "\r\n|[\n\r\u2028\u2029\u0085]"; 473 private static Pattern separatorPattern() { 474 Pattern sp = separatorPattern; 475 if (sp == null) 476 separatorPattern = sp = Pattern.compile(LINE_SEPARATOR_PATTERN); 477 return sp; 478 } 479 480 483 private Pattern floatPattern; 484 private Pattern decimalPattern; 485 private void buildFloatAndDecimalPattern() { 486 String digit = "([0-9]|(\\p{javaDigit}))"; 488 String exponent = "([eE][+-]?"+digit+"+)?"; 489 String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+ 490 groupSeparator+digit+digit+digit+")+)"; 491 String numeral = "(("+digit+"++)|"+groupedNumeral+")"; 493 String decimalNumeral = "("+numeral+"|"+numeral + 494 decimalSeparator + digit + "*+|"+ decimalSeparator + 495 digit + "++)"; 496 String nonNumber = "(NaN|"+nanString+"|Infinity|"+ 497 infinityString+")"; 498 String positiveFloat = "(" + positivePrefix + decimalNumeral + 499 positiveSuffix + exponent + ")"; 500 String negativeFloat = "(" + negativePrefix + decimalNumeral + 501 negativeSuffix + exponent + ")"; 502 String decimal = "(([-+]?" + decimalNumeral + exponent + ")|"+ 503 positiveFloat + "|" + negativeFloat + ")"; 504 String hexFloat = 505 "[-+]?0[xX][0-9a-fA-F]*\\.[0-9a-fA-F]+([pP][-+]?[0-9]+)?"; 506 String positiveNonNumber = "(" + positivePrefix + nonNumber + 507 positiveSuffix + ")"; 508 String negativeNonNumber = "(" + negativePrefix + nonNumber + 509 negativeSuffix + ")"; 510 String signedNonNumber = "(([-+]?"+nonNumber+")|" + 511 positiveNonNumber + "|" + 512 negativeNonNumber + ")"; 513 floatPattern = Pattern.compile(decimal + "|" + hexFloat + "|" + 514 signedNonNumber); 515 decimalPattern = Pattern.compile(decimal); 516 } 517 private Pattern floatPattern() { 518 if (floatPattern == null) { 519 buildFloatAndDecimalPattern(); 520 } 521 return floatPattern; 522 } 523 private Pattern decimalPattern() { 524 if (decimalPattern == null) { 525 buildFloatAndDecimalPattern(); 526 } 527 return decimalPattern; 528 } 529 530 532 540 private Scanner(Readable source, Pattern pattern) { 541 if (source == null) 542 throw new NullPointerException ("source"); 543 if (pattern == null) 544 throw new NullPointerException ("pattern"); 545 this.source = source; 546 delimPattern = pattern; 547 buf = CharBuffer.allocate(BUFFER_SIZE); 548 buf.limit(0); 549 matcher = delimPattern.matcher(buf); 550 matcher.useTransparentBounds(true); 551 matcher.useAnchoringBounds(false); 552 useLocale(Locale.getDefault()); 553 } 554 555 562 public Scanner(Readable source) { 563 this(source, WHITESPACE_PATTERN); 564 } 565 566 574 public Scanner(InputStream source) { 575 this(new InputStreamReader(source), WHITESPACE_PATTERN); 576 } 577 578 589 public Scanner(InputStream source, String charsetName) { 590 this(makeReadable(source, charsetName), WHITESPACE_PATTERN); 591 } 592 593 private static Readable makeReadable(InputStream source, 594 String charsetName) 595 { 596 if (source == null) 597 throw new NullPointerException ("source"); 598 InputStreamReader isr = null; 599 try { 600 isr = new InputStreamReader(source, charsetName); 601 } catch (UnsupportedEncodingException uee) { 602 IllegalArgumentException iae = new IllegalArgumentException (); 603 iae.initCause(uee); 604 throw iae; 605 } 606 return isr; 607 } 608 609 618 public Scanner(File source) 619 throws FileNotFoundException 620 { 621 this((ReadableByteChannel)(new FileInputStream(source).getChannel())); 622 } 623 624 636 public Scanner(File source, String charsetName) 637 throws FileNotFoundException 638 { 639 this((ReadableByteChannel)(new FileInputStream(source).getChannel()), 640 charsetName); 641 } 642 643 649 public Scanner(String source) { 650 this(new StringReader(source), WHITESPACE_PATTERN); 651 } 652 653 661 public Scanner(ReadableByteChannel source) { 662 this(makeReadable(source), WHITESPACE_PATTERN); 663 } 664 665 private static Readable makeReadable(ReadableByteChannel source) { 666 if (source == null) 667 throw new NullPointerException ("source"); 668 String defaultCharsetName = 669 java.nio.charset.Charset.defaultCharset().name(); 670 return Channels.newReader(source, 671 java.nio.charset.Charset.defaultCharset().name()); 672 } 673 674 685 public Scanner(ReadableByteChannel source, String charsetName) { 686 this(makeReadable(source, charsetName), WHITESPACE_PATTERN); 687 } 688 689 private static Readable makeReadable(ReadableByteChannel source, 690 String charsetName) 691 { 692 if (source == null) 693 throw new NullPointerException ("source"); 694 if (!Charset.isSupported(charsetName)) 695 throw new IllegalArgumentException (charsetName); 696 return Channels.newReader(source, charsetName); 697 } 698 699 701 private void saveState() { 702 savedScannerPosition = position; 703 } 704 705 private void revertState() { 706 this.position = savedScannerPosition; 707 savedScannerPosition = -1; 708 skipped = false; 709 } 710 711 private boolean revertState(boolean b) { 712 this.position = savedScannerPosition; 713 savedScannerPosition = -1; 714 skipped = false; 715 return b; 716 } 717 718 private void cacheResult(Pattern p) { 719 hasNextPattern = p; 720 hasNextResult = matcher.group(); 721 hasNextPosition = matcher.end(); 722 } 723 724 private void clearCaches() { 726 hasNextPattern = null; 727 typeCache = null; 728 } 729 730 private String getCachedResult() { 732 position = hasNextPosition; 733 hasNextPattern = null; 734 typeCache = null; 735 return hasNextResult; 736 } 737 738 private void useTypeCache() { 740 if (closed) 741 throw new IllegalStateException ("Scanner closed"); 742 position = hasNextPosition; 743 hasNextPattern = null; 744 typeCache = null; 745 } 746 747 private void readInput() { 749 if (buf.limit() == buf.capacity()) 750 makeSpace(); 751 752 int p = buf.position(); 754 buf.position(buf.limit()); 755 buf.limit(buf.capacity()); 756 757 int n = 0; 758 try { 759 n = source.read(buf); 760 } catch (IOException ioe) { 761 lastException = ioe; 762 n = -1; 763 } 764 765 if (n == -1) { 766 sourceClosed = true; 767 needInput = false; 768 } 769 770 if (n > 0) 771 needInput = false; 772 773 buf.limit(buf.position()); 775 buf.position(p); 776 } 777 778 private boolean makeSpace() { 781 clearCaches(); 782 int offset = savedScannerPosition == -1 ? 783 position : savedScannerPosition; 784 buf.position(offset); 785 if (offset > 0) { 787 buf.compact(); 788 translateSavedIndexes(offset); 789 position -= offset; 790 buf.flip(); 791 return true; 792 } 793 int newSize = buf.capacity() * 2; 795 CharBuffer newBuf = CharBuffer.allocate(newSize); 796 newBuf.put(buf); 797 newBuf.flip(); 798 translateSavedIndexes(offset); 799 position -= offset; 800 buf = newBuf; 801 matcher.reset(buf); 802 return true; 803 } 804 805 private void translateSavedIndexes(int offset) { 808 if (savedScannerPosition != -1) 809 savedScannerPosition -= offset; 810 } 811 812 private void throwFor() { 815 skipped = false; 816 if ((sourceClosed) && (position == buf.limit())) 817 throw new NoSuchElementException (); 818 else 819 throw new InputMismatchException (); 820 } 821 822 private boolean hasTokenInBuffer() { 826 matchValid = false; 827 matcher.usePattern(delimPattern); 828 matcher.region(position, buf.limit()); 829 830 if (matcher.lookingAt()) 832 position = matcher.end(); 833 834 if (position == buf.limit()) 836 return false; 837 838 return true; 839 } 840 841 856 private String getCompleteTokenInBuffer(Pattern pattern) { 857 matchValid = false; 858 859 matcher.usePattern(delimPattern); 861 if (!skipped) { matcher.region(position, buf.limit()); 863 if (matcher.lookingAt()) { 864 if (matcher.hitEnd() && !sourceClosed) { 867 needInput = true; 868 return null; 869 } 870 skipped = true; 872 position = matcher.end(); 873 } 874 } 875 876 if (position == buf.limit()) { 878 if (sourceClosed) 879 return null; 880 needInput = true; 881 return null; 882 } 883 884 889 matcher.region(position, buf.limit()); 891 boolean foundNextDelim = matcher.find(); 892 if (foundNextDelim && (matcher.end() == position)) { 893 foundNextDelim = matcher.find(); 897 } 898 if (foundNextDelim) { 899 if (matcher.requireEnd() && !sourceClosed) { 906 needInput = true; 907 return null; 908 } 909 int tokenEnd = matcher.start(); 910 if (pattern == null) { 912 pattern = FIND_ANY_PATTERN; 914 } 915 matcher.usePattern(pattern); 917 matcher.region(position, tokenEnd); 918 if (matcher.matches()) { 919 String s = matcher.group(); 920 position = matcher.end(); 921 return s; 922 } else { return null; 924 } 925 } 926 927 if (sourceClosed) { 930 if (pattern == null) { 931 pattern = FIND_ANY_PATTERN; 933 } 934 matcher.usePattern(pattern); 936 matcher.region(position, buf.limit()); 937 if (matcher.matches()) { 938 String s = matcher.group(); 939 position = matcher.end(); 940 return s; 941 } 942 return null; 944 } 945 946 needInput = true; 949 return null; 950 } 951 952 private String findPatternInBuffer(Pattern pattern, int horizon) { 955 matchValid = false; 956 matcher.usePattern(pattern); 957 int bufferLimit = buf.limit(); 958 int horizonLimit = -1; 959 int searchLimit = bufferLimit; 960 if (horizon > 0) { 961 horizonLimit = position + horizon; 962 if (horizonLimit < bufferLimit) 963 searchLimit = horizonLimit; 964 } 965 matcher.region(position, searchLimit); 966 if (matcher.find()) { 967 if (matcher.hitEnd() && (!sourceClosed)) { 968 if (searchLimit != horizonLimit) { 970 needInput = true; 972 return null; 973 } 974 if ((searchLimit == horizonLimit) && matcher.requireEnd()) { 976 needInput = true; 980 return null; 981 } 982 } 983 position = matcher.end(); 985 return matcher.group(); 986 } 987 988 if (sourceClosed) 989 return null; 990 991 if ((horizon == 0) || (searchLimit != horizonLimit)) 994 needInput = true; 995 return null; 996 } 997 998 private String matchPatternInBuffer(Pattern pattern) { 1001 matchValid = false; 1002 matcher.usePattern(pattern); 1003 matcher.region(position, buf.limit()); 1004 if (matcher.lookingAt()) { 1005 if (matcher.hitEnd() && (!sourceClosed)) { 1006 needInput = true; 1008 return null; 1009 } 1010 position = matcher.end(); 1011 return matcher.group(); 1012 } 1013 1014 if (sourceClosed) 1015 return null; 1016 1017 needInput = true; 1019 return null; 1020 } 1021 1022 private void ensureOpen() { 1024 if (closed) 1025 throw new IllegalStateException ("Scanner closed"); 1026 } 1027 1028 1030 1043 public void close() { 1044 if (closed) 1045 return; 1046 if (source instanceof Closeable) { 1047 try { 1048 ((Closeable)source).close(); 1049 } catch (IOException ioe) { 1050 lastException = ioe; 1051 } 1052 } 1053 sourceClosed = true; 1054 source = null; 1055 closed = true; 1056 } 1057 1058 1065 public IOException ioException() { 1066 return lastException; 1067 } 1068 1069 1075 public Pattern delimiter() { 1076 return delimPattern; 1077 } 1078 1079 1085 public Scanner useDelimiter(Pattern pattern) { 1086 delimPattern = pattern; 1087 return this; 1088 } 1089 1090 1101 public Scanner useDelimiter(String pattern) { 1102 delimPattern = patternCache.forName(pattern); 1103 return this; 1104 } 1105 1106 1115 public Locale locale() { 1116 return this.locale; 1117 } 1118 1119 1129 public Scanner useLocale(Locale locale) { 1130 if (locale.equals(this.locale)) 1131 return this; 1132 1133 this.locale = locale; 1134 DecimalFormat df = 1135 (DecimalFormat)NumberFormat.getNumberInstance(locale); 1136 DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale); 1137 1138 groupSeparator = "\\" + dfs.getGroupingSeparator(); 1141 decimalSeparator = "\\" + dfs.getDecimalSeparator(); 1142 1143 nanString = "\\Q" + dfs.getNaN() + "\\E"; 1146 infinityString = "\\Q" + dfs.getInfinity() + "\\E"; 1147 positivePrefix = df.getPositivePrefix(); 1148 if (positivePrefix.length() > 0) 1149 positivePrefix = "\\Q" + positivePrefix + "\\E"; 1150 negativePrefix = df.getNegativePrefix(); 1151 if (negativePrefix.length() > 0) 1152 negativePrefix = "\\Q" + negativePrefix + "\\E"; 1153 positiveSuffix = df.getPositiveSuffix(); 1154 if (positiveSuffix.length() > 0) 1155 positiveSuffix = "\\Q" + positiveSuffix + "\\E"; 1156 negativeSuffix = df.getNegativeSuffix(); 1157 if (negativeSuffix.length() > 0) 1158 negativeSuffix = "\\Q" + negativeSuffix + "\\E"; 1159 1160 integerPattern = null; 1163 floatPattern = null; 1164 1165 return this; 1166 } 1167 1168 1177 public int radix() { 1178 return this.defaultRadix; 1179 } 1180 1181 1196 public Scanner useRadix(int radix) { 1197 if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) 1198 throw new IllegalArgumentException ("radix:"+radix); 1199 1200 if (this.defaultRadix == radix) 1201 return this; 1202 this.defaultRadix = radix; 1203 integerPattern = null; 1205 return this; 1206 } 1207 1208 private void setRadix(int radix) { 1211 if (this.radix != radix) { 1212 integerPattern = null; 1214 this.radix = radix; 1215 } 1216 } 1217 1218 1237 public MatchResult match() { 1238 if (!matchValid) 1239 throw new IllegalStateException ("No match result available"); 1240 return matcher.toMatchResult(); 1241 } 1242 1243 1250 public String toString() { 1251 StringBuilder sb = new StringBuilder (); 1252 sb.append("java.util.Scanner"); 1253 sb.append("[delimiters=" + delimPattern + "]"); 1254 sb.append("[position=" + position + "]"); 1255 sb.append("[match valid=" + matchValid + "]"); 1256 sb.append("[need input=" + needInput + "]"); 1257 sb.append("[source closed=" + sourceClosed + "]"); 1258 sb.append("[skipped=" + skipped + "]"); 1259 sb.append("[group separator=" + groupSeparator + "]"); 1260 sb.append("[decimal separator=" + decimalSeparator + "]"); 1261 sb.append("[positive prefix=" + positivePrefix + "]"); 1262 sb.append("[negative prefix=" + negativePrefix + "]"); 1263 sb.append("[positive suffix=" + positiveSuffix + "]"); 1264 sb.append("[negative suffix=" + negativeSuffix + "]"); 1265 sb.append("[NaN string=" + nanString + "]"); 1266 sb.append("[infinity string=" + infinityString + "]"); 1267 return sb.toString(); 1268 } 1269 1270 1279 public boolean hasNext() { 1280 ensureOpen(); 1281 saveState(); 1282 while (!sourceClosed) { 1283 if (hasTokenInBuffer()) 1284 return revertState(true); 1285 readInput(); 1286 } 1287 boolean result = hasTokenInBuffer(); 1288 return revertState(result); 1289 } 1290 1291 1303 public String next() { 1304 ensureOpen(); 1305 clearCaches(); 1306 1307 while (true) { 1308 String token = getCompleteTokenInBuffer(null); 1309 if (token != null) { 1310 matchValid = true; 1311 skipped = false; 1312 return token; 1313 } 1314 if (needInput) 1315 readInput(); 1316 else 1317 throwFor(); 1318 } 1319 } 1320 1321 1328 public void remove() { 1329 throw new UnsupportedOperationException (); 1330 } 1331 1332 1345 public boolean hasNext(String pattern) { 1346 return hasNext(patternCache.forName(pattern)); 1347 } 1348 1349 1363 public String next(String pattern) { 1364 return next(patternCache.forName(pattern)); 1365 } 1366 1367 1378 public boolean hasNext(Pattern pattern) { 1379 ensureOpen(); 1380 if (pattern == null) 1381 throw new NullPointerException (); 1382 hasNextPattern = null; 1383 saveState(); 1384 1385 while (true) { 1386 if (getCompleteTokenInBuffer(pattern) != null) { 1387 matchValid = true; 1388 cacheResult(pattern); 1389 return revertState(true); 1390 } 1391 if (needInput) 1392 readInput(); 1393 else 1394 return revertState(false); 1395 } 1396 } 1397 1398 1410 public String next(Pattern pattern) { 1411 ensureOpen(); 1412 if (pattern == null) 1413 throw new NullPointerException (); 1414 1415 if (hasNextPattern == pattern) 1417 return getCachedResult(); 1418 clearCaches(); 1419 1420 while (true) { 1422 String token = getCompleteTokenInBuffer(pattern); 1423 if (token != null) { 1424 matchValid = true; 1425 skipped = false; 1426 return token; 1427 } 1428 if (needInput) 1429 readInput(); 1430 else 1431 throwFor(); 1432 } 1433 } 1434 1435 1443 public boolean hasNextLine() { 1444 saveState(); 1445 String result = findWithinHorizon( 1446 ".*("+LINE_SEPARATOR_PATTERN+")|.+$", 0); 1447 revertState(); 1448 return (result != null); 1449 } 1450 1451 1467 public String nextLine() { 1468 String result = findWithinHorizon( 1469 ".*("+LINE_SEPARATOR_PATTERN+")|.+$", 0); 1470 if (result == null) 1471 throw new NoSuchElementException ("No line found"); 1472 MatchResult mr = this.match(); 1473 String lineSep = mr.group(1); 1474 if (lineSep != null) 1475 result = result.substring(0, result.length() - lineSep.length()); 1476 if (result == null) 1477 throw new NoSuchElementException (); 1478 else 1479 return result; 1480 } 1481 1482 1484 1496 public String findInLine(String pattern) { 1497 return findInLine(patternCache.forName(pattern)); 1498 } 1499 1500 1518 public String findInLine(Pattern pattern) { 1519 ensureOpen(); 1520 if (pattern == null) 1521 throw new NullPointerException (); 1522 clearCaches(); 1523 1524 int endPosition = 0; 1526 saveState(); 1527 while (true) { 1528 String token = findPatternInBuffer(separatorPattern(), 0); 1529 if (token != null) { 1530 endPosition = matcher.start(); 1531 break; } 1533 if (needInput) { 1534 readInput(); 1535 } else { 1536 endPosition = buf.limit(); 1537 break; } 1539 } 1540 revertState(); 1541 int horizonForLine = endPosition - position; 1542 1543 return findWithinHorizon(pattern, horizonForLine); 1545 } 1546 1547 1561 public String findWithinHorizon(String pattern, int horizon) { 1562 return findWithinHorizon(patternCache.forName(pattern), horizon); 1563 } 1564 1565 1595 public String findWithinHorizon(Pattern pattern, int horizon) { 1596 ensureOpen(); 1597 if (pattern == null) 1598 throw new NullPointerException (); 1599 if (horizon < 0) 1600 throw new IllegalArgumentException ("horizon < 0"); 1601 clearCaches(); 1602 1603 while (true) { 1605 String token = findPatternInBuffer(pattern, horizon); 1606 if (token != null) { 1607 matchValid = true; 1608 return token; 1609 } 1610 if (needInput) 1611 readInput(); 1612 else 1613 break; } 1615 return null; 1616 } 1617 1618 1641 public Scanner skip(Pattern pattern) { 1642 ensureOpen(); 1643 if (pattern == null) 1644 throw new NullPointerException (); 1645 clearCaches(); 1646 1647 while (true) { 1649 String token = matchPatternInBuffer(pattern); 1650 if (token != null) { 1651 matchValid = true; 1652 position = matcher.end(); 1653 return this; 1654 } 1655 if (needInput) 1656 readInput(); 1657 else 1658 throw new NoSuchElementException (); 1659 } 1660 } 1661 1662 1674 public Scanner skip(String pattern) { 1675 return skip(patternCache.forName(pattern)); 1676 } 1677 1678 1680 1690 public boolean hasNextBoolean() { 1691 return hasNext(boolPattern()); 1692 } 1693 1694 1706 public boolean nextBoolean() { 1707 clearCaches(); 1708 return Boolean.parseBoolean(next(boolPattern())); 1709 } 1710 1711 1720 public boolean hasNextByte() { 1721 return hasNextByte(defaultRadix); 1722 } 1723 1724 1734 public boolean hasNextByte(int radix) { 1735 setRadix(radix); 1736 boolean result = hasNext(integerPattern()); 1737 if (result) { try { 1739 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? 1740 processIntegerToken(hasNextResult) : 1741 hasNextResult; 1742 typeCache = Byte.parseByte(s, radix); 1743 } catch (NumberFormatException nfe) { 1744 result = false; 1745 } 1746 } 1747 return result; 1748 } 1749 1750 1765 public byte nextByte() { 1766 return nextByte(defaultRadix); 1767 } 1768 1769 1795 public byte nextByte(int radix) { 1796 if ((typeCache != null) && (typeCache instanceof Byte )) { 1798 byte val = ((Byte )typeCache).byteValue(); 1799 useTypeCache(); 1800 return val; 1801 } 1802 setRadix(radix); 1803 clearCaches(); 1804 try { 1806 String s = next(integerPattern()); 1807 if (matcher.group(SIMPLE_GROUP_INDEX) == null) 1808 s = processIntegerToken(s); 1809 return Byte.parseByte(s, radix); 1810 } catch (NumberFormatException nfe) { 1811 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 1813 } 1814 } 1815 1816 1825 public boolean hasNextShort() { 1826 return hasNextShort(defaultRadix); 1827 } 1828 1829 1839 public boolean hasNextShort(int radix) { 1840 setRadix(radix); 1841 boolean result = hasNext(integerPattern()); 1842 if (result) { try { 1844 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? 1845 processIntegerToken(hasNextResult) : 1846 hasNextResult; 1847 typeCache = Short.parseShort(s, radix); 1848 } catch (NumberFormatException nfe) { 1849 result = false; 1850 } 1851 } 1852 return result; 1853 } 1854 1855 1870 public short nextShort() { 1871 return nextShort(defaultRadix); 1872 } 1873 1874 1900 public short nextShort(int radix) { 1901 if ((typeCache != null) && (typeCache instanceof Short )) { 1903 short val = ((Short )typeCache).shortValue(); 1904 useTypeCache(); 1905 return val; 1906 } 1907 setRadix(radix); 1908 clearCaches(); 1909 try { 1911 String s = next(integerPattern()); 1912 if (matcher.group(SIMPLE_GROUP_INDEX) == null) 1913 s = processIntegerToken(s); 1914 return Short.parseShort(s, radix); 1915 } catch (NumberFormatException nfe) { 1916 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 1918 } 1919 } 1920 1921 1930 public boolean hasNextInt() { 1931 return hasNextInt(defaultRadix); 1932 } 1933 1934 1944 public boolean hasNextInt(int radix) { 1945 setRadix(radix); 1946 boolean result = hasNext(integerPattern()); 1947 if (result) { try { 1949 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? 1950 processIntegerToken(hasNextResult) : 1951 hasNextResult; 1952 typeCache = Integer.parseInt(s, radix); 1953 } catch (NumberFormatException nfe) { 1954 result = false; 1955 } 1956 } 1957 return result; 1958 } 1959 1960 1965 private String processIntegerToken(String token) { 1966 String result = token.replaceAll(""+groupSeparator, ""); 1967 boolean isNegative = false; 1968 int preLen = negativePrefix.length(); 1969 if ((preLen > 0) && result.startsWith(negativePrefix)) { 1970 isNegative = true; 1971 result = result.substring(preLen); 1972 } 1973 int sufLen = negativeSuffix.length(); 1974 if ((sufLen > 0) && result.endsWith(negativeSuffix)) { 1975 isNegative = true; 1976 result = result.substring(result.length() - sufLen, 1977 result.length()); 1978 } 1979 if (isNegative) 1980 result = "-" + result; 1981 return result; 1982 } 1983 1984 1999 public int nextInt() { 2000 return nextInt(defaultRadix); 2001 } 2002 2003 2029 public int nextInt(int radix) { 2030 if ((typeCache != null) && (typeCache instanceof Integer )) { 2032 int val = ((Integer )typeCache).intValue(); 2033 useTypeCache(); 2034 return val; 2035 } 2036 setRadix(radix); 2037 clearCaches(); 2038 try { 2040 String s = next(integerPattern()); 2041 if (matcher.group(SIMPLE_GROUP_INDEX) == null) 2042 s = processIntegerToken(s); 2043 return Integer.parseInt(s, radix); 2044 } catch (NumberFormatException nfe) { 2045 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 2047 } 2048 } 2049 2050 2059 public boolean hasNextLong() { 2060 return hasNextLong(defaultRadix); 2061 } 2062 2063 2073 public boolean hasNextLong(int radix) { 2074 setRadix(radix); 2075 boolean result = hasNext(integerPattern()); 2076 if (result) { try { 2078 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? 2079 processIntegerToken(hasNextResult) : 2080 hasNextResult; 2081 typeCache = Long.parseLong(s, radix); 2082 } catch (NumberFormatException nfe) { 2083 result = false; 2084 } 2085 } 2086 return result; 2087 } 2088 2089 2104 public long nextLong() { 2105 return nextLong(defaultRadix); 2106 } 2107 2108 2134 public long nextLong(int radix) { 2135 if ((typeCache != null) && (typeCache instanceof Long )) { 2137 long val = ((Long )typeCache).longValue(); 2138 useTypeCache(); 2139 return val; 2140 } 2141 setRadix(radix); 2142 clearCaches(); 2143 try { 2144 String s = next(integerPattern()); 2145 if (matcher.group(SIMPLE_GROUP_INDEX) == null) 2146 s = processIntegerToken(s); 2147 return Long.parseLong(s, radix); 2148 } catch (NumberFormatException nfe) { 2149 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 2151 } 2152 } 2153 2154 2162 private String processFloatToken(String token) { 2163 String result = token.replaceAll(groupSeparator, ""); 2164 if (!decimalSeparator.equals("\\.")) 2165 result = result.replaceAll(decimalSeparator, "."); 2166 boolean isNegative = false; 2167 int preLen = negativePrefix.length(); 2168 if ((preLen > 0) && result.startsWith(negativePrefix)) { 2169 isNegative = true; 2170 result = result.substring(preLen); 2171 } 2172 int sufLen = negativeSuffix.length(); 2173 if ((sufLen > 0) && result.endsWith(negativeSuffix)) { 2174 isNegative = true; 2175 result = result.substring(result.length() - sufLen, 2176 result.length()); 2177 } 2178 if (result.equals(nanString)) 2179 result = "NaN"; 2180 if (result.equals(infinityString)) 2181 result = "Infinity"; 2182 if (isNegative) 2183 result = "-" + result; 2184 2185 Matcher m = NON_ASCII_DIGIT.matcher(result); 2187 if (m.find()) { 2188 StringBuilder inASCII = new StringBuilder (); 2189 for (int i=0; i<result.length(); i++) { 2190 char nextChar = result.charAt(i); 2191 if (Character.isDigit(nextChar)) { 2192 int d = Character.digit(nextChar, 10); 2193 if (d != -1) 2194 inASCII.append(d); 2195 else 2196 inASCII.append(nextChar); 2197 } else { 2198 inASCII.append(nextChar); 2199 } 2200 } 2201 result = inASCII.toString(); 2202 } 2203 2204 return result; 2205 } 2206 2207 2216 public boolean hasNextFloat() { 2217 setRadix(10); 2218 boolean result = hasNext(floatPattern()); 2219 if (result) { try { 2221 String s = processFloatToken(hasNextResult); 2222 typeCache = Float.valueOf(Float.parseFloat(s)); 2223 } catch (NumberFormatException nfe) { 2224 result = false; 2225 } 2226 } 2227 return result; 2228 } 2229 2230 2257 public float nextFloat() { 2258 if ((typeCache != null) && (typeCache instanceof Float )) { 2260 float val = ((Float )typeCache).floatValue(); 2261 useTypeCache(); 2262 return val; 2263 } 2264 setRadix(10); 2265 clearCaches(); 2266 try { 2267 return Float.parseFloat(processFloatToken(next(floatPattern()))); 2268 } catch (NumberFormatException nfe) { 2269 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 2271 } 2272 } 2273 2274 2283 public boolean hasNextDouble() { 2284 setRadix(10); 2285 boolean result = hasNext(floatPattern()); 2286 if (result) { try { 2288 String s = processFloatToken(hasNextResult); 2289 typeCache = Double.valueOf(Double.parseDouble(s)); 2290 } catch (NumberFormatException nfe) { 2291 result = false; 2292 } 2293 } 2294 return result; 2295 } 2296 2297 2324 public double nextDouble() { 2325 if ((typeCache != null) && (typeCache instanceof Double )) { 2327 double val = ((Double )typeCache).doubleValue(); 2328 useTypeCache(); 2329 return val; 2330 } 2331 setRadix(10); 2332 clearCaches(); 2333 try { 2335 return Double.parseDouble(processFloatToken(next(floatPattern()))); 2336 } catch (NumberFormatException nfe) { 2337 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 2339 } 2340 } 2341 2342 2344 2354 public boolean hasNextBigInteger() { 2355 return hasNextBigInteger(defaultRadix); 2356 } 2357 2358 2369 public boolean hasNextBigInteger(int radix) { 2370 setRadix(radix); 2371 boolean result = hasNext(integerPattern()); 2372 if (result) { try { 2374 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? 2375 processIntegerToken(hasNextResult) : 2376 hasNextResult; 2377 typeCache = new BigInteger(s, radix); 2378 } catch (NumberFormatException nfe) { 2379 result = false; 2380 } 2381 } 2382 return result; 2383 } 2384 2385 2401 public BigInteger nextBigInteger() { 2402 return nextBigInteger(defaultRadix); 2403 } 2404 2405 2426 public BigInteger nextBigInteger(int radix) { 2427 if ((typeCache != null) && (typeCache instanceof BigInteger)) { 2429 BigInteger val = (BigInteger)typeCache; 2430 useTypeCache(); 2431 return val; 2432 } 2433 setRadix(radix); 2434 clearCaches(); 2435 try { 2437 String s = next(integerPattern()); 2438 if (matcher.group(SIMPLE_GROUP_INDEX) == null) 2439 s = processIntegerToken(s); 2440 return new BigInteger(s, radix); 2441 } catch (NumberFormatException nfe) { 2442 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 2444 } 2445 } 2446 2447 2457 public boolean hasNextBigDecimal() { 2458 setRadix(10); 2459 boolean result = hasNext(decimalPattern()); 2460 if (result) { try { 2462 String s = processFloatToken(hasNextResult); 2463 typeCache = new BigDecimal(s); 2464 } catch (NumberFormatException nfe) { 2465 result = false; 2466 } 2467 } 2468 return result; 2469 } 2470 2471 2491 public BigDecimal nextBigDecimal() { 2492 if ((typeCache != null) && (typeCache instanceof BigDecimal)) { 2494 BigDecimal val = (BigDecimal)typeCache; 2495 useTypeCache(); 2496 return val; 2497 } 2498 setRadix(10); 2499 clearCaches(); 2500 try { 2502 String s = processFloatToken(next(decimalPattern())); 2503 return new BigDecimal(s); 2504 } catch (NumberFormatException nfe) { 2505 position = matcher.start(); throw new InputMismatchException (nfe.getMessage()); 2507 } 2508 } 2509} 2510 2511 | Popular Tags |