You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/07/10 15:57:11 UTC
svn commit: r420525 - in
/incubator/harmony/enhanced/classlib/trunk/modules/luni/src:
main/java/java/util/Scanner.java
main/java/org/apache/harmony/luni/util/ExternalMessages.properties
test/java/tests/api/java/util/ScannerTest.java
Author: tellison
Date: Mon Jul 10 06:57:10 2006
New Revision: 420525
URL: http://svn.apache.org/viewvc?rev=420525&view=rev
Log:
Apply patch HARMONY-817 (Implementation of new methods hasNextInt(),nextInt(),hasNextInt(int),nextInt(int), in java.util.Scanner)
Modified:
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Scanner.java
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/ScannerTest.java
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Scanner.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Scanner.java?rev=420525&r1=420524&r2=420525&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Scanner.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Scanner.java Mon Jul 10 06:57:10 2006
@@ -65,7 +65,7 @@
"true|false", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
// The pattern matching anything
- private static final Pattern ANY_PATTERN = Pattern.compile("(?s).*");
+ private static final Pattern ANY_PATTERN = Pattern.compile("(?s).*"); //$NON-NLS-1$
private static final int DIPLOID = 2;
@@ -102,6 +102,8 @@
private IOException lastIOException;
private boolean matchSuccessful = false;
+
+ private DecimalFormat decimalFormat;
/**
* Constructs a scanner that uses File as its input. The default charset is
@@ -132,12 +134,12 @@
public Scanner(File src, String charsetName) throws FileNotFoundException {
if (null == src) {
throw new NullPointerException(org.apache.harmony.luni.util.Msg
- .getString("KA00a"));
+ .getString("KA00a")); //$NON-NLS-1$
}
FileInputStream fis = new FileInputStream(src);
if (null == charsetName) {
throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
- .getString("KA009"));
+ .getString("KA009")); //$NON-NLS-1$
}
try {
input = new InputStreamReader(fis, charsetName);
@@ -188,7 +190,7 @@
public Scanner(InputStream src, String charsetName) {
if (null == src) {
throw new NullPointerException(org.apache.harmony.luni.util.Msg
- .getString("KA00b"));
+ .getString("KA00b")); //$NON-NLS-1$
}
try {
input = new InputStreamReader(src, charsetName);
@@ -237,11 +239,11 @@
public Scanner(ReadableByteChannel src, String charsetName) {
if (null == src) {
throw new NullPointerException(org.apache.harmony.luni.util.Msg
- .getString("KA00d"));
+ .getString("KA00d")); //$NON-NLS-1$
}
if (null == charsetName) {
throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
- .getString("KA009"));
+ .getString("KA009")); //$NON-NLS-1$
}
try {
input = new InputStreamReader(Channels.newInputStream(src),
@@ -483,16 +485,48 @@
throw new NotYetImplementedException();
}
- //TODO: To implement this feature
+ /**
+ * Returns true if this scanner's next token can be translated into a valid
+ * int value in the default radix. The scanner does not advance past the
+ * input.
+ *
+ * @return true iff the next token in this scanner's input can be translated
+ * into a valid int value
+ * @throws IllegalStateException
+ * if the scanner has been closed
+ */
public boolean hasNextInt() {
- throw new NotYetImplementedException();
+ return hasNextInt(radix);
}
- //TODO: To implement this feature
+ /**
+ * Returns true if this scanner's next token can be translated into a valid
+ * int value in the specified radix. The scanner does not advance past the
+ * input.
+ *
+ * @param radix
+ * the radix used to translate the token into an int value
+ * @return true iff the next token in this scanner's input can be translated
+ * into a valid int value
+ * @throws IllegalStateException
+ * if the scanner has been closed
+ */
public boolean hasNextInt(int radix) {
- throw new NotYetImplementedException();
+ Pattern integerPattern = getIntegerPattern(radix);
+ boolean isIntValue = false;
+ String intString;
+ if (hasNext(integerPattern)) {
+ intString = removeLocaleInfo(matcher.group());
+ try {
+ Integer.parseInt(intString, radix);
+ isIntValue = true;
+ } catch (NumberFormatException e) {
+ matchSuccessful = false;
+ }
+ }
+ return isIntValue;
}
-
+
//TODO: To implement this feature
public boolean hasNextLine() {
throw new NotYetImplementedException();
@@ -700,14 +734,67 @@
throw new NotYetImplementedException();
}
- //TODO: To implement this feature
+ /**
+ * Translates the next token in this scanner's input into an int value and
+ * returns this value. This method may be blocked when it is waiting for
+ * input to scan, even if a previous invocation of hasNextInt() returned
+ * true. If this match succeeds, the scanner advances past the input that
+ * matched.
+ *
+ * The invocation of this method in the form nextInt() behaves in the same
+ * way as the invocaiton of nextInt(radix), the radix is the default radix
+ * of this scanner.
+ *
+ * @return the int value scanned from the input
+ * @throws IllegalStateException
+ * if this scanner has been closed
+ * @throws NoSuchElementException
+ * if input has been exhausted
+ * @throws InputMismatchException
+ * if the next token can not be translated into a valid int
+ * value
+ */
public int nextInt() {
- throw new NotYetImplementedException();
+ return nextInt(radix);
}
- //TODO: To implement this feature
+ /**
+ * Translates the next token in this scanner's input into an int value and
+ * returns this value. This method may be blocked when it is waiting for
+ * input to scan, even if a previous invocation of hasNextInt(radix)
+ * returned true. If this match succeeds, the scanner advances past the
+ * input that matched.
+ *
+ * If the next token matches the Integer regular expression successfully,
+ * the token is translated into an int value as following steps. At first
+ * all locale specific prefixes ,group separators, and locale specific
+ * suffixes are removed. Then non-ASCII digits are mapped into ASCII digits
+ * via Character.digit, a negative sign (-) is added if the locale specific
+ * negative prefixes and suffixes were present. At last the resulting String
+ * is passed to Integer.parseInt with the specified radix.
+ *
+ * @param radix
+ * the radix used to translate the token into an int value
+ * @return the int value scanned from the input
+ * @throws IllegalStateException
+ * if this scanner has been closed
+ * @throws NoSuchElementException
+ * if input has been exhausted
+ * @throws InputMismatchException
+ * if the next token can not be translated into a valid int
+ * value
+ */
public int nextInt(int radix) {
- throw new NotYetImplementedException();
+ String intString = nextIntegerToken(radix);
+ int intValue = 0;
+ try {
+ intValue = Integer.parseInt(intString, radix);
+ } catch (NumberFormatException e) {
+ matchSuccessful = false;
+ recoverPreviousStatus();
+ throw new InputMismatchException();
+ }
+ return intValue;
}
//TODO: To implement this feature
@@ -812,7 +899,7 @@
public Scanner useRadix(int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
- .getString("KA008", radix));
+ .getString("KA008", radix)); //$NON-NLS-1$
}
this.radix = radix;
return this;
@@ -888,6 +975,178 @@
*/
private void recoverPreviousStatus() {
findStartIndex = preStartIndex;
+ }
+
+ /*
+ * Get next token if it matches integer regular expression after removing
+ * locale related information
+ */
+ private String nextIntegerToken(int radix) {
+ Pattern integerPattern = getIntegerPattern(radix);
+ String tokenString = next(integerPattern);
+ String intString = removeLocaleInfo(tokenString);
+ return intString;
+ }
+
+ /*
+ * Get integer's pattern
+ */
+ private Pattern getIntegerPattern(int radix) {
+ if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
+ throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
+ .getString("KA00e", radix)); //$NON-NLS-1$
+ }
+ decimalFormat = (DecimalFormat) NumberFormat.getInstance(locale);
+
+ String allAvailableDigits="0123456789abcdefghijklmnopqrstuvwxyz"; //$NON-NLS-1$
+ String ASCIIDigit=allAvailableDigits.substring(0, radix);
+ String nonZeroASCIIDigit=allAvailableDigits.substring(1, radix);
+
+ StringBuilder digit = new StringBuilder("((?i)[").append(ASCIIDigit) //$NON-NLS-1$
+ .append("]|\\p{javaDigit})"); //$NON-NLS-1$
+ StringBuilder nonZeroDigit = new StringBuilder("((?i)[").append( //$NON-NLS-1$
+ nonZeroASCIIDigit).append("]|([\\p{javaDigit}&&[^0]]))"); //$NON-NLS-1$
+ StringBuilder numeral = getNumeral(digit, nonZeroDigit);
+
+ StringBuilder integer = new StringBuilder("(([-+]?(").append(numeral) //$NON-NLS-1$
+ .append(")))|(").append(addPositiveSign(numeral)).append(")|(") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(addNegativeSign(numeral)).append(")"); //$NON-NLS-1$
+
+ Pattern integerPattern = Pattern.compile(integer.toString());
+ return integerPattern;
+ }
+
+
+ private StringBuilder getNumeral(StringBuilder digit,
+ StringBuilder nonZeroDigit) {
+ char groupSeparator = decimalFormat.getDecimalFormatSymbols()
+ .getGroupingSeparator();
+ StringBuilder groupedNumeral = new StringBuilder("(").append( //$NON-NLS-1$
+ nonZeroDigit).append(digit).append("?").append(digit).append( //$NON-NLS-1$
+ "?(\\").append(groupSeparator).append(digit).append(digit) //$NON-NLS-1$
+ .append(digit).append(")+)"); //$NON-NLS-1$
+ StringBuilder numeral = new StringBuilder("((").append(digit).append( //$NON-NLS-1$
+ "++)|").append(groupedNumeral).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
+ return numeral;
+ }
+
+ /*
+ * Add the locale specific positive prefixes and suffixes to the pattern
+ */
+ private StringBuilder addPositiveSign(StringBuilder unSignNumeral) {
+ String positivePrefix = ""; //$NON-NLS-1$
+ String positiveSuffix = ""; //$NON-NLS-1$
+ if (!decimalFormat.getPositivePrefix().equals("")) { //$NON-NLS-1$
+ positivePrefix = "\\" + decimalFormat.getPositivePrefix(); //$NON-NLS-1$
+ }
+ if (!decimalFormat.getPositiveSuffix().equals("")) { //$NON-NLS-1$
+ positiveSuffix = "\\" + decimalFormat.getPositiveSuffix(); //$NON-NLS-1$
+ }
+ StringBuilder signedNumeral = new StringBuilder()
+ .append(positivePrefix).append(unSignNumeral).append(
+ positiveSuffix);
+ return signedNumeral;
+ }
+
+ /*
+ * Add the locale specific negative prefixes and suffixes to the pattern
+ */
+ private StringBuilder addNegativeSign(StringBuilder unSignNumeral) {
+ String negativePrefix = ""; //$NON-NLS-1$
+ String negativeSuffix = ""; //$NON-NLS-1$
+ if (!decimalFormat.getNegativePrefix().equals("")) { //$NON-NLS-1$
+ negativePrefix = "\\" + decimalFormat.getNegativePrefix(); //$NON-NLS-1$
+ }
+ if (!decimalFormat.getNegativeSuffix().equals("")) { //$NON-NLS-1$
+ negativeSuffix = "\\" + decimalFormat.getNegativeSuffix(); //$NON-NLS-1$
+ }
+ StringBuilder signedNumeral = new StringBuilder()
+ .append(negativePrefix).append(unSignNumeral).append(
+ negativeSuffix);
+ return signedNumeral;
+ }
+
+ /*
+ * Remove the locale specific prefixes, group separators, and locale
+ * specific suffixes from input string
+ */
+ private String removeLocaleInfo(String token) {
+ StringBuilder tokenBuilder = new StringBuilder(token);
+ boolean negative = removeLocaleSign(tokenBuilder);
+ // Remove group separator
+ String groupSeparator = String.valueOf(decimalFormat
+ .getDecimalFormatSymbols().getGroupingSeparator());
+ int separatorIndex = -1;
+ while (-1 != (separatorIndex = tokenBuilder.indexOf(groupSeparator))) {
+ tokenBuilder.delete(separatorIndex, separatorIndex + 1);
+ }
+ // Remove decimal separator
+ String decimalSeparator = String.valueOf(decimalFormat
+ .getDecimalFormatSymbols().getDecimalSeparator());
+ separatorIndex = tokenBuilder.indexOf(decimalSeparator);
+ StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
+
+ for (int i = 0; i < tokenBuilder.length(); i++) {
+ if (-1 != Character.digit(tokenBuilder.charAt(i),
+ Character.MAX_RADIX)) {
+ result.append(tokenBuilder.charAt(i));
+ }
+ }
+ // Token is NaN or Infinity
+ if (0 == result.length()) {
+ result = tokenBuilder;
+ }
+ if (-1 != separatorIndex) {
+ result.insert(separatorIndex, "."); //$NON-NLS-1$
+ }
+ // If input is negative
+ if (negative) {
+ result.insert(0, '-');
+ }
+ return result.toString();
+ }
+
+ /*
+ * remove positive and negative sign from the parameter stringBuilder, and
+ * return whether the input string is negative
+ */
+ private boolean removeLocaleSign(StringBuilder tokenBuilder) {
+ String positivePrefix = decimalFormat.getPositivePrefix();
+ String positiveSuffix = decimalFormat.getPositiveSuffix();
+ String negativePrefix = decimalFormat.getNegativePrefix();
+ String negativeSuffix = decimalFormat.getNegativeSuffix();
+
+ if (0 == tokenBuilder.indexOf("+")) { //$NON-NLS-1$
+ tokenBuilder.delete(0, 1);
+ }
+ if (!positivePrefix.equals("") //$NON-NLS-1$
+ && 0 == tokenBuilder.indexOf(positivePrefix)) {
+ tokenBuilder.delete(0, positivePrefix.length());
+ }
+ if (!positiveSuffix.equals("") //$NON-NLS-1$
+ && -1 != tokenBuilder.indexOf(positiveSuffix)) {
+ tokenBuilder.delete(
+ tokenBuilder.length() - positiveSuffix.length(),
+ tokenBuilder.length());
+ }
+ boolean negative = false;
+ if (0 == tokenBuilder.indexOf("-")) { //$NON-NLS-1$
+ tokenBuilder.delete(0, 1);
+ negative = true;
+ }
+ if (!negativePrefix.equals("") //$NON-NLS-1$
+ && 0 == tokenBuilder.indexOf(negativePrefix)) {
+ tokenBuilder.delete(0, negativePrefix.length());
+ negative = true;
+ }
+ if (!negativeSuffix.equals("") //$NON-NLS-1$
+ && -1 != tokenBuilder.indexOf(negativeSuffix)) {
+ tokenBuilder.delete(
+ tokenBuilder.length() - negativeSuffix.length(),
+ tokenBuilder.length());
+ negative = true;
+ }
+ return negative;
}
/*
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties?rev=420525&r1=420524&r2=420525&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties Mon Jul 10 06:57:10 2006
@@ -299,4 +299,5 @@
KA00b=InputStream is null
KA00c=Readable is null
KA00d=ReadableByteChannel is null
+KA00e=Radix {0} is less than Character.MIN_RADIX or greater than Character.MAX_RADIX
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/ScannerTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/ScannerTest.java?rev=420525&r1=420524&r2=420525&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/ScannerTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/ScannerTest.java Mon Jul 10 06:57:10 2006
@@ -928,6 +928,385 @@
/**
* @throws IOException
+ * @tests java.util.Scanner#nextInt(int)
+ */
+ public void test_nextIntI() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextInt(10));
+ assertEquals(456, s.nextInt(10));
+ try {
+ s.nextInt(10);
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertEquals(38, s.nextInt(5));
+ try {
+ s.nextInt(5);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt(10));
+ assertEquals(23456, s.nextInt(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt(10));
+ assertEquals(23456, s.nextInt(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextInt(10));
+ try {
+ s.nextInt(5);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+ assertEquals(162, s.nextInt(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt(10));
+ assertEquals(23456, s.nextInt(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("E3456");
+ assertEquals(930902, s.nextInt(16));
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(930902, s.nextInt(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt(10));
+
+ /*
+ * There are three types of negative prefix all in all. '' '-' '(' There
+ * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
+ * must be used togethor. Prefix '-' and suffix '-' must be used
+ * exclusively.
+ */
+
+ /*
+ * According to Integer regular expression: Integer :: = ( [-+]? (*
+ * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
+ * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
+ * recognized by scanner with locale ar_AE, (123) shouble be recognized
+ * by scanner with locale mk_MK. But this is not the case on RI.
+ */
+ s = new Scanner("-123 123- -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextInt(10));
+ // The following test case fails on RI
+ assertEquals(-123, s.nextInt(10));
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("-123 123- (123)");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextInt(10));
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ // The following test case fails on RI
+ assertEquals(-123, s.nextInt(10));
+
+ // If the parameter radix is illegal, the following test cases fail on
+ // RI
+ try {
+ s.nextInt(Character.MIN_RADIX - 1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ s.nextInt(Character.MAX_RADIX + 1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextInt()
+ */
+ public void test_nextInt() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextInt());
+ assertEquals(456, s.nextInt());
+ try {
+ s.nextInt();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertEquals(38, s.nextInt());
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt());
+ assertEquals(23456, s.nextInt());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt());
+ assertEquals(23456, s.nextInt());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextInt());
+ s.useRadix(5);
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+ s.useRadix(10);
+ assertEquals(162, s.nextInt());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt());
+ assertEquals(23456, s.nextInt());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("E3456");
+ s.useRadix(16);
+ assertEquals(930902, s.nextInt());
+
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ s.useRadix(16);
+ assertEquals(930902, s.nextInt());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt());
+
+ /*
+ * There are three types of negative prefix all in all. '' '-' '(' There
+ * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
+ * must be used togethor. Prefix '-' and suffix '-' must be used
+ * exclusively.
+ */
+
+ /*
+ * According to Integer regular expression: Integer :: = ( [-+]? (*
+ * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
+ * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
+ * recognized by scanner with locale ar_AE, (123) shouble be recognized
+ * by scanner with locale mk_MK. But this is not the case on RI.
+ */
+ s = new Scanner("-123 123- -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextInt());
+ // The following test case fails on RI
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("-123 123- (123)");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ // The following test case fails on RI
+ assertEquals(-123, s.nextInt());
+ }
+
+ /**
+ * @throws IOException
* @tests java.util.Scanner#hasNext()
*/
public void test_hasNext() throws IOException {
@@ -1196,6 +1575,353 @@
assertFalse(s.nextBoolean());
assertFalse(s.hasNextBoolean());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextInt(int)
+ */
+ public void test_hasNextIntI() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextInt(10));
+ assertTrue(s.hasNextInt(10));
+ assertEquals(456, s.nextInt(10));
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextInt(5));
+ assertEquals(38, s.nextInt(5));
+ assertFalse(s.hasNextInt(5));
+ try {
+ s.nextInt(5);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ assertFalse(s.hasNextInt(10));
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt(10));
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextInt(10));
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt(10));
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextInt(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06662");
+ assertTrue(s.hasNextInt(10));
+ assertFalse(s.hasNextInt(5));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextInt(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextInt(10));
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("E3456");
+ assertTrue(s.hasNextInt(16));
+ assertEquals(930902, s.nextInt(16));
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextInt(16));
+ assertEquals(930902, s.nextInt(16));
+
+ // If parameter radix is illegal, the following test case fails on RI
+ try {
+ s.hasNextInt(Character.MIN_RADIX - 1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(12300, s.nextInt(10));
+
+ /*
+ * There are three types of negative prefix all in all. '' '-' '(' There
+ * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
+ * must be used togethor. Prefix '-' and suffix '-' must be used
+ * exclusively.
+ */
+
+ /*
+ * According to Integer regular expression: Integer :: = ( [-+]? (*
+ * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
+ * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
+ * recognized by scanner with locale ar_AE, (123) shouble be recognized
+ * by scanner with locale mk_MK. But this is not the case on RI.
+ */
+ s = new Scanner("-123 123- -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextInt(10));
+ assertEquals(-123, s.nextInt(10));
+ // The following test case fails on RI
+ assertTrue(s.hasNextInt(10));
+ assertEquals(-123, s.nextInt(10));
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("-123 123- (123)");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextInt(10));
+ assertEquals(-123, s.nextInt(10));
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ // The following test case fails on RI
+ assertTrue(s.hasNextInt(10));
+ assertEquals(-123, s.nextInt(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextInt()
+ */
+ public void test_hasNextInt() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextInt());
+ assertEquals(123, s.nextInt());
+ assertEquals(456, s.nextInt());
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertTrue(s.hasNextInt());
+ assertEquals(38, s.nextInt());
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // Expected
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ assertFalse(s.hasNextInt());
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt());
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextInt());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt());
+ s.useLocale(new Locale("it", "CH"));
+ assertTrue(s.hasNextInt());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06662");
+ s.useRadix(5);
+ assertFalse(s.hasNextInt());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextInt());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextInt());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextInt());
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("E3456");
+ s.useRadix(16);
+ assertTrue(s.hasNextInt());
+ assertEquals(930902, s.nextInt());
+
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ s.useRadix(16);
+ assertTrue(s.hasNextInt());
+ assertEquals(930902, s.nextInt());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt());
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt());
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt());
+ assertEquals(12300, s.nextInt());
+
+ /*
+ * There are three types of negative prefix all in all. '' '-' '(' There
+ * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
+ * must be used togethor. Prefix '-' and suffix '-' must be used
+ * exclusively.
+ */
+
+ /*
+ * According to Integer regular expression: Integer :: = ( [-+]? (*
+ * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
+ * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
+ * recognized by scanner with locale ar_AE, (123) shouble be recognized
+ * by scanner with locale mk_MK. But this is not the case on RI.
+ */
+ s = new Scanner("-123 123- -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextInt());
+ assertEquals(-123, s.nextInt());
+ // The following test case fails on RI
+ assertTrue(s.hasNextInt());
+ assertEquals(-123, s.nextInt());
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+
+ s = new Scanner("-123 123- (123)");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextInt());
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail("Should throw InputMismatchException");
+ } catch (InputMismatchException e) {
+ // expected
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ // The following test case fails on RI
+ assertTrue(s.hasNextInt());
+ assertEquals(-123, s.nextInt());
}
private static class MockStringReader extends StringReader {