Fix several Scanner issues.
- Update the Matcher properly.
- Support \u221E for infinity.
- Support non-decimal starting digits.
- Update test to remove some bogus assertions.
Change-Id: Ie7c57019dea49c441bed35d9a6814ec040a96de0
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
index cc6a0f0..2f96394 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
@@ -135,10 +135,11 @@
} catch (FileNotFoundException expected) {
}
+ // Bogus test : Depends on the order in which expections are thrown.
try {
s = new Scanner(tmpFile, null);
fail();
- } catch (FileNotFoundException expected) {
+ } catch (IllegalArgumentException expected) {
}
tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
@@ -2659,17 +2660,22 @@
assertEquals(-123, s.nextByte(10));
}
+ // This is a bogus test : The cached value is returned only if the radix
+ // matches.
public void test_hasNextByteI_cache() throws IOException{
//regression for HARMONY-2063
s = new Scanner("123 45");
assertTrue(s.hasNextByte(8));
- assertEquals(83, s.nextByte());
+ // Note that the cached value isn't returned here.
+ assertEquals(123, s.nextByte());
assertEquals(45, s.nextByte());
s = new Scanner("123 45");
assertTrue(s.hasNextByte(10));
assertTrue(s.hasNextByte(8));
- assertEquals(83, s.nextByte());
+
+ // The values are returned according to the supplied radix.
+ assertEquals(123, s.nextByte());
assertEquals(45, s.nextByte());
s = new Scanner("-123 -45");
@@ -2937,7 +2943,7 @@
//regression for HARMONY-2063
s = new Scanner("123 123456789123456789");
assertTrue(s.hasNextBigInteger(16));
- assertEquals(new BigInteger("291"), s.nextBigInteger());
+ assertEquals(new BigInteger("123"), s.nextBigInteger());
assertEquals(new BigInteger("123456789123456789"), s.nextBigInteger());
s = new Scanner("123456789123456789 456");
@@ -3287,13 +3293,13 @@
//regression for HARMONY-2063
s = new Scanner("123 456");
assertTrue(s.hasNextInt(16));
- assertEquals(291, s.nextInt(10));
+ assertEquals(123, s.nextInt(10));
assertEquals(456, s.nextInt());
s = new Scanner("123 456");
assertTrue(s.hasNextInt(16));
assertTrue(s.hasNextInt(8));
- assertEquals(83, s.nextInt());
+ assertEquals(123, s.nextInt());
assertEquals(456, s.nextInt());
s = new Scanner("-123 -456 -789");
@@ -3926,13 +3932,13 @@
//regression for HARMONY-2063
s = new Scanner("123 456");
assertTrue(s.hasNextShort(16));
- assertEquals(291, s.nextShort());
+ assertEquals(123, s.nextShort());
assertEquals(456, s.nextShort());
s = new Scanner("123 456");
assertTrue(s.hasNextShort(16));
assertTrue(s.hasNextShort(8));
- assertEquals(83, s.nextShort());
+ assertEquals(123, s.nextShort());
assertEquals(456, s.nextShort());
s = new Scanner("-123 -456 -789");
@@ -4122,13 +4128,13 @@
//regression for HARMONY-2063
s = new Scanner("123 456");
assertTrue(s.hasNextLong(16));
- assertEquals(291, s.nextLong());
+ assertEquals(123, s.nextLong());
assertEquals(456, s.nextLong());
s = new Scanner("123 456");
assertTrue(s.hasNextLong(16));
assertTrue(s.hasNextLong(8));
- assertEquals(83, s.nextLong());
+ assertEquals(123, s.nextLong());
assertEquals(456, s.nextLong());
s = new Scanner("-123 -456 -789");
diff --git a/ojluni/src/main/java/java/util/Scanner.java b/ojluni/src/main/java/java/util/Scanner.java
index c9504ad..64824c5 100755
--- a/ojluni/src/main/java/java/util/Scanner.java
+++ b/ojluni/src/main/java/java/util/Scanner.java
@@ -465,12 +465,16 @@
private int SIMPLE_GROUP_INDEX = 5;
private String buildIntegerPatternString() {
String radixDigits = digits.substring(0, radix);
+ // Android changed : Support non-decimal starting digits. (i.e, a-z are valid radix digits).
+ String nonZeroRadixDigits = "((?i)[" + digits.substring(1, radix) + "]|(" + non0Digit + "))";
+
// \\p{javaDigit} is not guaranteed to be appropriate
// here but what can we do? The final authority will be
// whatever parse method is invoked, so ultimately the
// Scanner will do the right thing
String digit = "((?i)["+radixDigits+"]|\\p{javaDigit})";
- String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+
+ // Android changed : Support non-decimal starting digits.
+ String groupedNumeral = "("+nonZeroRadixDigits+digit+"?"+digit+"?("+
groupSeparator+digit+digit+digit+")+)";
// digit++ is the possessive form which is necessary for reducing
// backtracking that would otherwise cause unacceptable performance
@@ -681,7 +685,11 @@
}
private static CharsetDecoder toDecoder(String charsetName) {
- Objects.requireNonNull(charsetName, "charsetName");
+ // Android-changed: Throw an IAE instead of an NPE.
+ // Objects.requireNonNull(charsetName, "charsetName");
+ if (charsetName == null) {
+ throw new IllegalArgumentException("charsetName == null");
+ }
try {
return Charset.forName(charsetName).newDecoder();
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -863,6 +871,9 @@
// Restore current position and limit for reading
buf.limit(buf.position());
buf.position(p);
+ // Android changed : The matcher implementation eagerly calls toString() so we'll have
+ // to update its input whenever the buffer limit, position etc. changes.
+ matcher.reset(buf);
}
// After this method is called there will either be an exception
@@ -1307,6 +1318,11 @@
// The next operation should occur in the specified radix but
// the default is left untouched.
private void setRadix(int radix) {
+ // Android-changed : Complain loudly if a bogus radix is being set.
+ if (radix > Character.MAX_RADIX) {
+ throw new IllegalArgumentException("radix == " + radix);
+ }
+
if (this.radix != radix) {
// Force rebuilding and recompilation of radix dependent patterns
integerPattern = null;
@@ -2300,6 +2316,9 @@
result = "NaN";
if (result.equals(infinityString))
result = "Infinity";
+ // Android-changed: Match the infinity symbol.
+ if (result.equals("\u221E"))
+ result = "Infinity";
if (isNegative)
result = "-" + result;