You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gh...@apache.org on 2006/07/05 19:01:52 UTC

svn commit: r419279 - in /incubator/harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/util/Scanner.java test/java/tests/api/java/util/ScannerTest.java

Author: gharley
Date: Wed Jul  5 10:01:51 2006
New Revision: 419279

URL: http://svn.apache.org/viewvc?rev=419279&view=rev
Log:
HARMONY 766 : [luni] Implement new methods java.util.Scanner.hasNext() and hasNext(String)

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Scanner.java
    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=419279&r1=419278&r2=419279&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 Wed Jul  5 10:01:51 2006
@@ -68,7 +68,7 @@
     // Default radix
     private static final int DEFAULT_RADIX = 10;
 
-    private static final int READ_TRUNK_SIZE = 1024;
+    private static final int DEFAULT_TRUNK_SIZE = 1024;
 
     // The input source of scanner
     private Readable input;
@@ -143,6 +143,7 @@
             }
             throw new IllegalArgumentException(e.getMessage());
         }
+        initialization();
     }
 
     /**
@@ -153,6 +154,7 @@
      */
     public Scanner(String src) {
         input = new StringReader(src);
+        initialization();
     }
 
     /**
@@ -187,6 +189,7 @@
         } catch (UnsupportedEncodingException e) {
             throw new IllegalArgumentException(e.getMessage());
         }
+        initialization();
     }
 
     /**
@@ -197,10 +200,10 @@
      */
     public Scanner(Readable src) {
         if (null == src) {
-            throw new NullPointerException(org.apache.harmony.luni.util.Msg
-                    .getString("KA00c"));
+            throw new NullPointerException();
         }
         input = src;
+        initialization();
     }
 
     /**
@@ -240,6 +243,7 @@
         } catch (UnsupportedEncodingException e) {
             throw new IllegalArgumentException(e.getMessage());
         }
+        initialization();
     }
 
     /**
@@ -291,9 +295,18 @@
         throw new NotYetImplementedException();
     }
 
-    //TODO: To implement this feature
+    /**
+     * Returns true if this scanner has next token. This method may be blocked
+     * when it is waiting for input to scan. This scanner does not advance past
+     * the input.
+     * 
+     * @return true 
+     *             iff this scanner has next token
+     * @throws IllegalStateException
+     *             if the scanner has been closed
+     */
     public boolean hasNext() {
-        throw new NotYetImplementedException();
+        return hasNext(ANY_PATTERN);
     }
 
     /**
@@ -330,9 +343,24 @@
     }
 
 
-    //TODO: To implement this feature
+    /**
+     * Returns true if this scanner's next token matches the pattern constructed
+     * from the specified string. This method may be blocked when it is waiting
+     * for input to scan. This scanner does not advance past the input that
+     * matched the pattern.
+     * 
+     * The invocation of this method in the form hasNext(pattern) behaves in the
+     * same way as the invocaiton of hasNext(Pattern.compile(pattern)).
+     * 
+     * @param pattern
+     *            the string specifying the pattern to scan for
+     * @return true 
+     *            iff this scanner's next token matches the specified pattern
+     * @throws IllegalStateException
+     *             if the scanner has been closed
+     */
     public boolean hasNext(String pattern) {
-        throw new NotYetImplementedException();
+        return hasNext(Pattern.compile(pattern));
     }
 
     //TODO: To implement this feature
@@ -677,6 +705,15 @@
     }
 
     /*
+     * Initial some components.
+     */
+    private void initialization() {
+        buffer = CharBuffer.allocate(DEFAULT_TRUNK_SIZE);
+        buffer.limit(0);
+        matcher = delimiter.matcher(buffer);
+    }
+    
+    /*
      * Check the scanner's state, if it is closed, IllegalStateException will be
      * thrown.
      */
@@ -791,7 +828,7 @@
     }
 
     /*
-     * Handle some special case
+     * Handle some special cases
      */
     private boolean setHeadTokenRegion(int findIndex) {
         int tokenStartIndex;
@@ -840,42 +877,53 @@
 
     /*
      * Read more data from underlying Readable. Return false if nothing is
-     * available.
+     * available or I/O operation fails.
      */
     private boolean readMore() {
-        int oldBufferSize = (buffer == null ? 0 : buffer.limit());
-        int oldBufferCapacity = (buffer == null ? 0 : buffer.capacity());
+        int oldPosition = buffer.position();
+        int oldLimit = buffer.limit();
         // Increase capacity if empty space is not enough
-        if (oldBufferSize >= oldBufferCapacity / 2) {
-            expandBuffer(oldBufferSize, oldBufferCapacity);
+        if (buffer.limit() >= buffer.capacity()) {
+            expandBuffer();
         }
 
         // Read input resource
         int readCount = 0;
         try {
             buffer.limit(buffer.capacity());
-            buffer.position(oldBufferSize);
-            // TODO Writes test cases to test whether this == 0 is correct.
+            buffer.position(oldLimit);
             while ((readCount = input.read(buffer)) == 0) {
                 // nothing to do here
             }
         } catch (IOException e) {
+            readCount = (buffer.position() - oldLimit);
             lastIOException = e;
         }
+
+        // The return value of readable.read() method can be used to record the
+        // actual characters read. Consider the scenario: readable puts 4 chars into
+        // buffer and then an IOException is thrown out. In this case, buffer is
+        // actually grown, but readable.read() will never return.
+
         buffer.flip();
-        buffer.position(bufferLength);
-        bufferLength = buffer.length() + bufferLength;
-        buffer.position(0);
+        buffer.position(oldPosition);
+        if (-1 != readCount)
+            bufferLength = readCount + bufferLength;
         return readCount != -1;
     }
 
     // Expand the size of internal buffer.
-    private void expandBuffer(int oldBufferSize, int oldBufferCapacity) {
-        int newCapacity = oldBufferCapacity * DIPLOID + READ_TRUNK_SIZE;
+    private void expandBuffer() {
+        int oldPosition = buffer.position();
+        int oldCapacity = buffer.capacity();
+        int oldLimit = buffer.limit();
+        int newCapacity = oldCapacity * DIPLOID;
         char[] newBuffer = new char[newCapacity];
         if (buffer != null) {
-            System.arraycopy(buffer.array(), 0, newBuffer, 0, oldBufferSize);
+            System.arraycopy(buffer.array(), 0, newBuffer, 0, oldLimit);
         }
         buffer = CharBuffer.wrap(newBuffer, 0, newCapacity);
+        buffer.position(oldPosition);
+        buffer.limit(oldLimit);
     }
 }

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=419279&r1=419278&r2=419279&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 Wed Jul  5 10:01:51 2006
@@ -676,6 +676,84 @@
     
     /**
      * @throws IOException
+     * @tests java.util.Scanner#hasNext()
+     */
+    public void test_hasNext() throws IOException {
+        s = new Scanner("1##2").useDelimiter("\\#");
+        assertTrue(s.hasNext());
+        assertEquals("1", s.next());
+        assertEquals("", s.next());
+        assertEquals("2", s.next());
+        assertFalse(s.hasNext());
+        s.close();
+        try {
+            s.hasNext();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+
+        s = new Scanner("1( )2( )").useDelimiter("\\( \\)");
+        assertTrue(s.hasNext());
+        assertTrue(s.hasNext());
+        assertEquals("1", s.next());
+        assertEquals("2", s.next());
+
+        s = new Scanner("1 2  ").useDelimiter("( )");
+        assertEquals("1", s.next());
+        assertEquals("2", s.next());
+        assertTrue(s.hasNext());
+        assertEquals("", s.next());
+
+        s = new Scanner("1\n2  ");
+        assertEquals("1", s.next());
+        assertTrue(s.hasNext());
+        assertEquals("2", s.next());
+        assertFalse(s.hasNext());
+        // test boundary case
+        try {
+            s.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        s = new Scanner("1'\n'2  ");
+        assertEquals("1'", s.next());
+        assertTrue(s.hasNext());
+        assertEquals("'2", s.next());
+        assertFalse(s.hasNext());
+        // test boundary case
+        try {
+            s.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        s = new Scanner("  ");
+        assertFalse(s.hasNext());
+
+        // test socket inputStream
+
+        os.write("1 2".getBytes());
+        serverSocket.close();
+
+        s = new Scanner(client);
+        assertEquals("1", s.next());
+        assertTrue(s.hasNext());
+        assertEquals("2", s.next());
+        assertFalse(s.hasNext());
+        try {
+            s.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
+    
+    /**
+     * @throws IOException
      * @tests java.util.Scanner#hasNext(Pattern)
      */
     public void test_hasNextLPattern() throws IOException {
@@ -745,6 +823,76 @@
         assertFalse(s.hasNext(pattern));
         try {
             s.next(pattern);
+            fail("should throw InputMismatchException");
+        } catch (InputMismatchException e) {
+            // Expected
+        }
+    }
+    
+    /**
+     * @throws IOException
+     * @tests java.util.Scanner#hasNext(String)
+     */
+    public void test_hasNextLString() throws IOException {
+        s = new Scanner("aab@2@abb@").useDelimiter("\\@");
+        try {
+            s.hasNext((String)null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        
+        s = new Scanner("aab*b*").useDelimiter("\\*");
+        assertTrue(s.hasNext("a+b"));
+        assertEquals("aab", s.next("a+b"));
+        assertFalse(s.hasNext("a+b"));
+        try {
+            s.next("a+b");
+            fail("should throw InputMismatchException");
+        } catch (InputMismatchException e) {
+            // Expected
+        }
+        s.close();
+        try {
+            s.hasNext("a+b");
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+
+        s = new Scanner("WORD ? ");
+        assertTrue(s.hasNext("\\w+"));
+        assertEquals("WORD", s.next("\\w+"));
+        assertFalse(s.hasNext("\\w+"));
+        try {
+            s.next("\\w+");
+            fail("should throw InputMismatchException");
+        } catch (InputMismatchException e) {
+            // Expected
+        }
+
+        s = new Scanner("word1 word2  ");
+        assertEquals("word1", s.next("\\w+"));
+        assertEquals("word2", s.next("\\w+"));
+        // test boundary case
+        try {
+            s.next("\\w+");
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        // test socket inputStream
+
+        os.write("aab 2".getBytes());
+        serverSocket.close();
+
+        s = new Scanner(client);
+        assertTrue(s.hasNext("a*b"));
+        assertEquals("aab", s.next("a*b"));
+        assertFalse(s.hasNext("a*b"));
+        try {
+            s.next("a*b");
             fail("should throw InputMismatchException");
         } catch (InputMismatchException e) {
             // Expected