You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2005/08/20 15:56:51 UTC

svn commit: r234027 - in /jakarta/commons/proper/lang/trunk/src: java/org/apache/commons/lang/text/StrBuilder.java test/org/apache/commons/lang/text/StrBuilderTest.java

Author: scolebourne
Date: Sat Aug 20 06:56:44 2005
New Revision: 234027

URL: http://svn.apache.org/viewcvs?rev=234027&view=rev
Log:
Ensure that the reader is a proper view
(previously if the builder buffer changed due to appends after creating the reader these weren't picked up)

Modified:
    jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderTest.java

Modified: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java?rev=234027&r1=234026&r2=234027&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java (original)
+++ jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java Sat Aug 20 06:56:44 2005
@@ -15,7 +15,6 @@
  */
 package org.apache.commons.lang.text;
 
-import java.io.CharArrayReader;
 import java.io.Reader;
 import java.io.Writer;
 import java.util.Collection;
@@ -47,6 +46,14 @@
  *  </ul>
  * </li>
  * </ul>
+ * <li>Views
+ *  <ul>
+ *   <li>asTokenizer - uses the internal buffer as the source of a StrTokenizer</li>
+ *   <li>asReader - uses the internal buffer as the source of a Reader</li>
+ *   <li>asWriter - allows a Writer to write directly to the internal buffer</li>
+ *  </ul>
+ * </li>
+ * </ul>
  * <p>
  * The aim has been to provide an API that mimics very closely what StringBuffer
  * provides, but with additional methods. It should be noted that some edge cases,
@@ -1907,20 +1914,43 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Creates a tokenizer using the current contents of this builder.
+     * <p>
+     * This method allows the contents of the builder to be tokenized.
+     * The tokenizer will be setup to tokenize on space, tab, newline
+     * and formfeed (as per StringTokenizer). These values can be changed
+     * on the tokenizer class, before retrieving the tokens.
+     * <p>
+     * Note that the internal character array is shared between the two
+     * objects and no synchronization occurs, so you must not alter this
+     * builder in one thread while tokenizing it in another thread.
+     *
+     * @return a StrTokenizer instance
+     */
+    public StrTokenizer asTokenizer() {
+        return new StrTokenizer(buffer);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Gets the contents of this builder as a Reader.
      * <p>
      * This method allows the contents of the builder to be read
      * using any standard method that expects a Reader.
-     * The current implementation returns a CharArrayReader, but
-     * you should not rely on this.
      * <p>
-     * Note that no synchronization occurs, so you must not alter this
+     * To use, simply create a <code>StrBuilder</code>, populate it with
+     * data, call <code>asReader</code>, and then read away.
+     * <p>
+     * Note that the internal character array is shared between the two
+     * objects and no synchronization occurs, so you must not alter this
      * builder in one thread while reading it in another thread.
+     * Note also that close has no effect on the reader, and that
+     * marking is supported.
      *
      * @return a reader that reads from this builder
      */
     public Reader asReader() {
-        return new CharArrayReader(buffer, 0, size);
+        return new StrBuilderReader();
     }
 
     //-----------------------------------------------------------------------
@@ -1933,7 +1963,9 @@
      * To use, simply create a <code>StrBuilder</code>,
      * call <code>asWriter</code>, and populate away. The data is available
      * at any time using the methods of the <code>StrBuilder</code>.
-     * Note however, that no synchronization occurs, so you must not read
+     * <p>
+     * Note that the internal character array is shared between the two
+     * objects and no synchronization occurs, so you must not alter this
      * the builder from one thread while writing in another thread.
      * Note also that close and flush have no effect on the writer.
      *
@@ -2028,6 +2060,85 @@
     protected void validateIndex(int index) {
         if (index < 0 || index > size) {
             throw new StringIndexOutOfBoundsException(index);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Inner class to allow StrBuilder to operate as a writer.
+     */
+    class StrBuilderReader extends Reader {
+        /** The current stream position. */
+        private int pos;
+        /** The last mark position. */
+        private int mark;
+
+        StrBuilderReader() {
+            super();
+        }
+
+        /** @inheritdoc */
+        public void close() {
+            // do nothing
+        }
+
+        /** @inheritdoc */
+        public int read() {
+            if (ready() == false) {
+                return -1;
+            }
+            return charAt(pos++);
+        }
+
+        /** @inheritdoc */
+        public int read(char b[], int off, int len) {
+            if (off < 0 || len < 0 || off > b.length ||
+                    (off + len) > b.length || (off + len) < 0) {
+                throw new IndexOutOfBoundsException();
+            }
+            if (len == 0) {
+                return 0;
+            }
+            if (pos >= size()) {
+                return -1;
+            }
+            if (pos + len > size()) {
+                len = size() - pos;
+            }
+            getChars(pos, pos + len, b, off);
+            pos += len;
+            return len;
+        }
+
+        public long skip(long n) {
+            if (pos + n > size()) {
+                n = size() - pos;
+            }
+            if (n < 0) {
+                return 0;
+            }
+            pos += n;
+            return n;
+        }
+
+        /** @inheritdoc */
+        public boolean ready() {
+            return pos < size();
+        }
+
+        /** @inheritdoc */
+        public boolean markSupported() {
+            return true;
+        }
+
+        /** @inheritdoc */
+        public void mark(int readAheadLimit) {
+            mark = pos;
+        }
+
+        /** @inheritdoc */
+        public void reset() {
+            pos = mark;
         }
     }
 

Modified: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderTest.java?rev=234027&r1=234026&r2=234027&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderTest.java (original)
+++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderTest.java Sat Aug 20 06:56:44 2005
@@ -1485,19 +1485,78 @@
 
     // -----------------------------------------------------------------------
     public void testAsReader() throws Exception {
-        StrBuilder sb = new StrBuilder ("some text");
+        StrBuilder sb = new StrBuilder("some text");
         Reader reader = sb.asReader();
+        assertEquals(true, reader.ready());
         char[] buf = new char[40];
         assertEquals(9, reader.read(buf));
         assertEquals("some text", new String(buf, 0, 9));
         
-        buf = new char[40];
-        assertEquals(-1, reader.read(buf));
+        assertEquals(-1, reader.read());
+        assertEquals(false, reader.ready());
+        assertEquals(0, reader.skip(2));
+        assertEquals(0, reader.skip(-1));
+        
+        assertEquals(true, reader.markSupported());
+        reader = sb.asReader();
+        assertEquals('s', reader.read());
+        reader.mark(-1);
+        char[] array = new char[3];
+        assertEquals(3, reader.read(array, 0, 3));
+        assertEquals('o', array[0]);
+        assertEquals('m', array[1]);
+        assertEquals('e', array[2]);
+        reader.reset();
+        assertEquals(1, reader.read(array, 1, 1));
+        assertEquals('o', array[0]);
+        assertEquals('o', array[1]);
+        assertEquals('e', array[2]);
+        assertEquals(2, reader.skip(2));
+        assertEquals(' ', reader.read());
+        
+        assertEquals(true, reader.ready());
+        reader.close();
+        assertEquals(true, reader.ready());
+        
+        reader = sb.asReader();
+        array = new char[3];
+        try {
+            reader.read(array, -1, 0);
+            fail();
+        } catch (IndexOutOfBoundsException ex) {}
+        try {
+            reader.read(array, 0, -1);
+            fail();
+        } catch (IndexOutOfBoundsException ex) {}
+        try {
+            reader.read(array, 100, 1);
+            fail();
+        } catch (IndexOutOfBoundsException ex) {}
+        try {
+            reader.read(array, 0, 100);
+            fail();
+        } catch (IndexOutOfBoundsException ex) {}
+        try {
+            reader.read(array, Integer.MAX_VALUE, Integer.MAX_VALUE);
+            fail();
+        } catch (IndexOutOfBoundsException ex) {}
+        
+        assertEquals(0, reader.read(array, 0, 0));
+        assertEquals(0, array[0]);
+        assertEquals(0, array[1]);
+        assertEquals(0, array[2]);
+        
+        reader.skip(9);
+        assertEquals(-1, reader.read(array, 0, 1));
+        
+        reader.reset();
+        array = new char[30];
+        assertEquals(9, reader.read(array, 0, 30));
     }
 
     //-----------------------------------------------------------------------
     public void testAsWriter() throws Exception {
-        StrBuilder sb = new StrBuilder ("base");
+        StrBuilder sb = new StrBuilder("base");
         Writer writer = sb.asWriter();
         
         writer.write('l');



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org