Author: niallp
Date: Mon Sep  5 23:34:43 2011
New Revision: 1165453

URL: http://svn.apache.org/viewvc?rev=1165453&view=rev
Log:
IO-277 ReaderInputStream enters infinite loop when it encounters an unmappable 
character - thanks to Mike Thomas

Modified:
    
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
    
commons/proper/io/trunk/src/main/java/org/apache/commons/io/output/WriterOutputStream.java
    
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java

Modified: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/ReaderInputStream.java?rev=1165453&r1=1165452&r2=1165453&view=diff
==============================================================================
--- 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
 (original)
+++ 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
 Mon Sep  5 23:34:43 2011
@@ -24,6 +24,7 @@ import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
 
 /**
  * {@link InputStream} implementation that reads a character stream from a 
{@link Reader}
@@ -100,17 +101,44 @@ public class ReaderInputStream extends I
      * Construct a new {@link ReaderInputStream}.
      * 
      * @param reader the target {@link Reader}
-     * @param charset the charset encoding
+     * @param encoder the charset encoder
+     * @since Commons IO 2.1
+     */
+    public ReaderInputStream(Reader reader, CharsetEncoder encoder) {
+        this(reader, encoder, DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Construct a new {@link ReaderInputStream}.
+     * 
+     * @param reader the target {@link Reader}
+     * @param encoder the charset encoder
      * @param bufferSize the size of the input buffer in number of characters
+     * @since Commons IO 2.1
      */
-    public ReaderInputStream(Reader reader, Charset charset, int bufferSize) {
+    public ReaderInputStream(Reader reader, CharsetEncoder encoder, int 
bufferSize) {
         this.reader = reader;
-        encoder = charset.newEncoder();
+        this.encoder = encoder;
         encoderIn = CharBuffer.allocate(bufferSize);
         encoderIn.flip();
     }
 
     /**
+     * Construct a new {@link ReaderInputStream}.
+     * 
+     * @param reader the target {@link Reader}
+     * @param charset the charset encoding
+     * @param bufferSize the size of the input buffer in number of characters
+     */
+    public ReaderInputStream(Reader reader, Charset charset, int bufferSize) {
+        this(reader,
+             charset.newEncoder()
+                    .onMalformedInput(CodingErrorAction.REPLACE)
+                    .onUnmappableCharacter(CodingErrorAction.REPLACE),
+             bufferSize);
+    }
+
+    /**
      * Construct a new {@link ReaderInputStream} with a default input buffer 
size of
      * 1024 characters.
      * 

Modified: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/output/WriterOutputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/output/WriterOutputStream.java?rev=1165453&r1=1165452&r2=1165453&view=diff
==============================================================================
--- 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/output/WriterOutputStream.java
 (original)
+++ 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/output/WriterOutputStream.java
 Mon Sep  5 23:34:43 2011
@@ -93,28 +93,61 @@ public class WriterOutputStream extends 
     private final CharBuffer decoderOut;
 
     /**
+     * Constructs a new {@link WriterOutputStream} with a default output 
buffer size of
+     * 1024 characters. The output buffer will only be flushed when it 
overflows or when
+     * {@link #flush()} or {@link #close()} is called.
+     * 
+     * @param writer the target {@link Writer}
+     * @param decoder the charset decoder
+     * @since Commons IO 2.1
+     */
+    public WriterOutputStream(Writer writer, CharsetDecoder decoder) {
+        this(writer, decoder, DEFAULT_BUFFER_SIZE, false);
+    }
+
+    /**
      * Constructs a new {@link WriterOutputStream}.
      * 
      * @param writer the target {@link Writer}
-     * @param charset the charset encoding
+     * @param decoder the charset decoder
      * @param bufferSize the size of the output buffer in number of characters
      * @param writeImmediately If <tt>true</tt> the output buffer will be 
flushed after each
      *                         write operation, i.e. all available data will 
be written to the
      *                         underlying {@link Writer} immediately. If 
<tt>false</tt>, the
      *                         output buffer will only be flushed when it 
overflows or when
      *                         {@link #flush()} or {@link #close()} is called.
+     * @since Commons IO 2.1
      */
-    public WriterOutputStream(Writer writer, Charset charset, int bufferSize, 
boolean writeImmediately) {
+    public WriterOutputStream(Writer writer, CharsetDecoder decoder, int 
bufferSize, boolean writeImmediately) {
         this.writer = writer;
-        decoder = charset.newDecoder();
-        decoder.onMalformedInput(CodingErrorAction.REPLACE);
-        decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
-        decoder.replaceWith("?");
+        this.decoder = decoder;
         this.writeImmediately = writeImmediately;
         decoderOut = CharBuffer.allocate(bufferSize);
     }
 
     /**
+     * Constructs a new {@link WriterOutputStream}.
+     * 
+     * @param writer the target {@link Writer}
+     * @param charset the charset encoding
+     * @param bufferSize the size of the output buffer in number of characters
+     * @param writeImmediately If <tt>true</tt> the output buffer will be 
flushed after each
+     *                         write operation, i.e. all available data will 
be written to the
+     *                         underlying {@link Writer} immediately. If 
<tt>false</tt>, the
+     *                         output buffer will only be flushed when it 
overflows or when
+     *                         {@link #flush()} or {@link #close()} is called.
+     */
+    public WriterOutputStream(Writer writer, Charset charset, int bufferSize, 
boolean writeImmediately) {
+        this(writer,
+             charset.newDecoder()
+                    .onMalformedInput(CodingErrorAction.REPLACE)
+                    .onUnmappableCharacter(CodingErrorAction.REPLACE)
+                    .replaceWith("?"),
+             bufferSize,
+             writeImmediately);
+    }
+
+    /**
      * Constructs a new {@link WriterOutputStream} with a default output 
buffer size of
      * 1024 characters. The output buffer will only be flushed when it 
overflows or when
      * {@link #flush()} or {@link #close()} is called.

Modified: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java?rev=1165453&r1=1165452&r2=1165453&view=diff
==============================================================================
--- 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java
 (original)
+++ 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java
 Mon Sep  5 23:34:43 2011
@@ -117,7 +117,6 @@ public class ReaderInputStreamTest {
      * @throws IOException
      */
     @Test
-    @Ignore
     public void testCharsetMismatchInfiniteLoop() throws IOException {
         // Input is UTF-8 bytes: 0xE0 0xB2 0xA0
         char[] inputChars = new char[] { (char) 0xE0, (char) 0xB2, (char) 0xA0 
};


Reply via email to