Author: niallp
Date: Sat Jan  5 07:24:10 2008
New Revision: 609152

URL: http://svn.apache.org/viewvc?rev=609152&view=rev
Log:
IO-138 new Reader implementation that handles any CharSequence (String, 
StringBuffer, StringBuilder or CharBuffer)

Added:
    
commons/proper/io/trunk/src/java/org/apache/commons/io/input/CharSequenceReader.java
   (with props)
    
commons/proper/io/trunk/src/test/org/apache/commons/io/input/CharSequenceReaderTest.java
   (with props)
Modified:
    commons/proper/io/trunk/RELEASE-NOTES.txt
    commons/proper/io/trunk/build-check-jdk13.xml

Modified: commons/proper/io/trunk/RELEASE-NOTES.txt
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/RELEASE-NOTES.txt?rev=609152&r1=609151&r2=609152&view=diff
==============================================================================
--- commons/proper/io/trunk/RELEASE-NOTES.txt (original)
+++ commons/proper/io/trunk/RELEASE-NOTES.txt Sat Jan  5 07:24:10 2008
@@ -33,6 +33,10 @@
 
 Enhancements from 1.3.2
 -----------------------
+- CharSequenceReader [IO-138]
+  - Add new Reader implementation that handles any CharSequence (String,
+    StringBuffer, StringBuilder or CharBuffer) 
+
 - ThesholdingOuputStream [IO-121]
   - Add a reset() method which sets the count of the bytes written back to 
zero.
 

Modified: commons/proper/io/trunk/build-check-jdk13.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/build-check-jdk13.xml?rev=609152&r1=609151&r2=609152&view=diff
==============================================================================
--- commons/proper/io/trunk/build-check-jdk13.xml (original)
+++ commons/proper/io/trunk/build-check-jdk13.xml Sat Jan  5 07:24:10 2008
@@ -61,6 +61,7 @@
                sourcepath="">
 
             <include name="**/*.java"/>
+            <exclude name="**/CharSequenceReader.java"/>
             <exclude name="**/RegexFileFilter.java"/>
 
         </javac>

Added: 
commons/proper/io/trunk/src/java/org/apache/commons/io/input/CharSequenceReader.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/java/org/apache/commons/io/input/CharSequenceReader.java?rev=609152&view=auto
==============================================================================
--- 
commons/proper/io/trunk/src/java/org/apache/commons/io/input/CharSequenceReader.java
 (added)
+++ 
commons/proper/io/trunk/src/java/org/apache/commons/io/input/CharSequenceReader.java
 Sat Jan  5 07:24:10 2008
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.input;
+
+import java.io.Reader;
+import java.io.Serializable;
+
+/**
+ * [EMAIL PROTECTED] Reader} implementation that can read from String, 
StringBuffer,
+ * StringBuilder or CharBuffer.
+ * <p>
+ * <strong>Note:</strong> Supports [EMAIL PROTECTED] #mark(int)} and [EMAIL 
PROTECTED] #reset()}.
+ *
+ * @version $Revision$ $Date$
+ * @since Commons IO 1.4
+ */
+public class CharSequenceReader extends Reader implements Serializable {
+
+    private static final StringBuilder EMPTY_BUILDER = new StringBuilder(0);
+    private final CharSequence charSequence;
+    private int idx;
+    private int mark;
+
+    /**
+     * Construct a new instance with the specified character sequence.
+     *
+     * @param charSequence The character sequence, may be <code>null</code>
+     */
+    public CharSequenceReader(CharSequence charSequence) {
+        this.charSequence = (charSequence != null ? charSequence : 
EMPTY_BUILDER);
+    }
+
+    /**
+     * Close resets the file back to the start and removes any marked position.
+     */
+    public void close() {
+        idx = 0;
+        mark = 0;
+    }
+
+    /**
+     * Mark the current position.
+     *
+     * @param readAheadLimit ignored
+     */
+    public void mark(int readAheadLimit) {
+        mark = idx;
+    }
+
+    /**
+     * Mark is supported (returns true).
+     *
+     * @return <code>true</code>
+     */
+    public boolean markSupported() {
+        return true;
+    }
+
+    /**
+     * Read a single character.
+     *
+     * @return the next character from the character sequence
+     * or -1 if the end has been reached.
+     */
+    public int read() {
+        if (idx >= charSequence.length()) {
+            return -1;
+        } else {
+            return (int)charSequence.charAt(idx++);
+        }
+    }
+
+    /**
+     * Read the sepcified number of characters into the array.
+     *
+     * @param array The array to store the characters in
+     * @param offset The starting position in the array to store
+     * @param length The maximum number of characters to read
+     * @return The number of characters read or -1 if there are
+     * no more
+     */
+    public int read(char[] array, int offset, int length) {
+        if (idx >= charSequence.length()) {
+            return -1;
+        }
+        if (array == null) {
+            throw new NullPointerException("Character array is missing");
+        }
+        if (length < 0 || (offset + length) > array.length) {
+            throw new IndexOutOfBoundsException("Array Size=" + array.length +
+                    ", offset=" + offset + ", length=" + length);
+        }
+        int count = 0;
+        for (int i = 0; i < length; i++) {
+            int c = read();
+            if (c == -1) {
+                return count;
+            }
+            array[offset + i] = (char)c;
+            count++;
+        }
+        return count;
+    }
+
+    /**
+     * Reset the reader to the last marked position (or the beginning if
+     * mark has not been called).
+     */
+    public void reset() {
+        idx = mark;
+    }
+
+    /**
+     * Skip the specified number of characters.
+     *
+     * @param n The number of characters to skip
+     * @return The actual number of characters skipped
+     */
+    public long skip(long n) {
+        if (n < 0) {
+            throw new IllegalArgumentException(
+                    "Number of characters to skip is less than zero: " + n);
+        }
+        if (idx >= charSequence.length()) {
+            return -1;
+        }
+        int dest = (int)Math.min(charSequence.length(), (idx + n));
+        int count = dest - idx;
+        idx = dest;
+        return count;
+    }
+
+    /**
+     * Return a String representation of the underlying
+     * character sequence.
+     *
+     * @return The contents of the character sequence
+     */
+    public String toString() {
+        return charSequence.toString();
+    }
+}

Propchange: 
commons/proper/io/trunk/src/java/org/apache/commons/io/input/CharSequenceReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/io/trunk/src/java/org/apache/commons/io/input/CharSequenceReader.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: 
commons/proper/io/trunk/src/test/org/apache/commons/io/input/CharSequenceReaderTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/org/apache/commons/io/input/CharSequenceReaderTest.java?rev=609152&view=auto
==============================================================================
--- 
commons/proper/io/trunk/src/test/org/apache/commons/io/input/CharSequenceReaderTest.java
 (added)
+++ 
commons/proper/io/trunk/src/test/org/apache/commons/io/input/CharSequenceReaderTest.java
 Sat Jan  5 07:24:10 2008
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io.input;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for [EMAIL PROTECTED] CharSequenceReader}.
+ *
+ * @version $Revision$ $Date$
+ */
+public class CharSequenceReaderTest extends TestCase {
+    private static final char NONE = (new char[1])[0];
+
+    /**
+     * Contruct a new test case.
+     * @param name The name of the test
+     */
+    public CharSequenceReaderTest(String name) {
+        super(name);
+    }
+
+    /** Test [EMAIL PROTECTED] Reader#close()}. */
+    public void testClose() throws IOException {
+        Reader reader = new CharSequenceReader("FooBar");
+        checkRead(reader, "Foo");
+        reader.close();
+        checkRead(reader, "Foo");
+    }
+
+    /** Test [EMAIL PROTECTED] Reader#markSupported()}. */
+    public void testMarkSupported() throws IOException {
+        Reader reader = new CharSequenceReader("FooBar");
+        assertTrue(reader.markSupported());
+    }
+
+    /** Test [EMAIL PROTECTED] Reader#mark(int)}. */
+    public void testMark() throws IOException {
+        Reader reader = new CharSequenceReader("FooBar");
+        checkRead(reader, "Foo");
+        reader.mark(0);
+        checkRead(reader, "Bar");
+        reader.reset();
+        checkRead(reader, "Bar");
+        reader.close();
+        checkRead(reader, "Foo");
+        reader.reset();
+        checkRead(reader, "Foo");
+    }
+
+    /** Test [EMAIL PROTECTED] Reader#skip(int)}. */
+    public void testSkip() throws IOException {
+        Reader reader = new CharSequenceReader("FooBar");
+        assertEquals(3, reader.skip(3));
+        checkRead(reader, "Bar");
+        assertEquals(-1, reader.skip(3));
+        reader.reset();
+        assertEquals(2, reader.skip(2));
+        assertEquals(4, reader.skip(10));
+        assertEquals(-1, reader.skip(1));
+        reader.close();
+        assertEquals(6, reader.skip(20));
+        assertEquals(-1, reader.read());
+    }
+
+    /** Test [EMAIL PROTECTED] Reader#read()}. */
+    public void testRead() throws IOException {
+        Reader reader = new CharSequenceReader("Foo");
+        assertEquals('F', reader.read());
+        assertEquals('o', reader.read());
+        assertEquals('o', reader.read());
+        assertEquals(-1, reader.read());
+        assertEquals(-1, reader.read());
+    }
+
+    /** Test [EMAIL PROTECTED] Reader#read(char[])}. */
+    public void testReadCharArray() throws IOException {
+        Reader reader = new CharSequenceReader("FooBar");
+        char[] chars = new char[2];
+        assertEquals(2, reader.read(chars));
+        checkArray(new char[] {'F', 'o'}, chars);
+        chars = new char[3];
+        assertEquals(3, reader.read(chars));
+        checkArray(new char[] {'o', 'B', 'a'}, chars);
+        chars = new char[3];
+        assertEquals(1, reader.read(chars));
+        checkArray(new char[] {'r', NONE, NONE}, chars);
+        assertEquals(-1, reader.read(chars));
+    }
+
+    /** Test [EMAIL PROTECTED] Reader#read(char[], int, int)}. */
+    public void testReadCharArrayPortion() throws IOException {
+        char[] chars = new char[10];
+        Reader reader = new CharSequenceReader("FooBar");
+        assertEquals(3, reader.read(chars, 3, 3));
+        checkArray(new char[] {NONE, NONE, NONE, 'F', 'o', 'o'}, chars);
+        assertEquals(3, reader.read(chars, 0, 3));
+        checkArray(new char[] {'B', 'a', 'r', 'F', 'o', 'o', NONE}, chars);
+        assertEquals(-1, reader.read(chars));
+    }
+
+    private void checkRead(Reader reader, String expected) throws IOException {
+        for (int i = 0; i < expected.length(); i++) {
+            assertEquals("Read[" + i + "] of '" + expected + "'", 
+                    (char)expected.charAt(i), (char)reader.read());
+        }
+    }
+    private void checkArray(char[] expected, char[] actual) throws IOException 
{
+        for (int i = 0; i < expected.length; i++) {
+            assertEquals("Compare[" +i + "]", expected[i], actual[i]);
+        }
+    }
+}

Propchange: 
commons/proper/io/trunk/src/test/org/apache/commons/io/input/CharSequenceReaderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/io/trunk/src/test/org/apache/commons/io/input/CharSequenceReaderTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL


Reply via email to