WriterOutputStream maps null Charset, Charset name, and CharsetEncoder
name to the platform default instead of throwing a NullPointerException.
MODIFY
src/changes/changes.xml
src/changes/changes.xml
@@ -127,11 +127,14 @@ The <action> type attribute can be add,update,fix,remove.
When deleting symlinks, File/PathUtils.deleteDirectory() changes file permissions of the target.
</action>
<action dev="ggregory" type="fix" due-to="Gary Gregory">
- ReaderInputStream maps null Charset, Charset name, and CharsetEmcoder to the platform default instead of throwing a NullPointerException.
+ ReaderInputStream maps null Charset, Charset name, and CharsetEncoder to the platform default instead of throwing a NullPointerException.
</action>
<action dev="ggregory" type="fix" due-to="Gary Gregory">
CharSequenceInputStream maps null Charset and Charset name to the platform default instead of throwing a NullPointerException.
</action>
+ <action dev="ggregory" type="fix" due-to="Gary Gregory">
+ WriterOutputStream maps null Charset, Charset name, and CharsetEncoder name to the platform default instead of throwing a NullPointerException.
+ </action>
<!-- ADD -->
<action issue="IO-726" dev="ggregory" type="fix" due-to="shollander, Gary Gregory">
Add MemoryMappedFileInputStream #215.

MODIFY
src/main/java/org/apache/commons/io/output/WriterOutputStream.java
src/main/java/org/apache/commons/io/output/WriterOutputStream.java
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
+import org.apache.commons.io.Charsets;
+import org.apache.commons.io.charset.CharsetDecoders;
+
/**
* {@link OutputStream} implementation that transforms a byte stream to a
* character stream using a specified charset encoding and writes the resulting
@@ -164,15 +167,16 @@ public WriterOutputStream(final Writer writer, final Charset charset) {
* output buffer will only be flushed when it overflows or when
* {@link #flush()} or {@link #close()} is called.
*/
- public WriterOutputStream(final Writer writer, final Charset charset, final int bufferSize,
- final boolean writeImmediately) {
+ public WriterOutputStream(final Writer writer, final Charset charset, final int bufferSize, final boolean writeImmediately) {
+ // @formatter:off
this(writer,
- charset.newDecoder()
+ Charsets.toCharset(charset).newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith("?"),
bufferSize,
writeImmediately);
+ // @formatter:on
}
/**
@@ -201,11 +205,10 @@ public WriterOutputStream(final Writer writer, final CharsetDecoder decoder) {
* {@link #flush()} or {@link #close()} is called.
* @since 2.1
*/
- public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize,
- final boolean writeImmediately) {
- checkIbmJdkWithBrokenUTF16( decoder.charset());
+ public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize, final boolean writeImmediately) {
+ checkIbmJdkWithBrokenUTF16(CharsetDecoders.toCharsetDecoder(decoder).charset());
this.writer = writer;
- this.decoder = decoder;
+ this.decoder = CharsetDecoders.toCharsetDecoder(decoder);
this.writeImmediately = writeImmediately;
decoderOut = CharBuffer.allocate(bufferSize);
}
@@ -236,7 +239,7 @@ public WriterOutputStream(final Writer writer, final String charsetName) {
*/
public WriterOutputStream(final Writer writer, final String charsetName, final int bufferSize,
final boolean writeImmediately) {
- this(writer, Charset.forName(charsetName), bufferSize, writeImmediately);
+ this(writer, Charsets.toCharset(charsetName), bufferSize, writeImmediately);
}
/**

MODIFY
src/test/java/org/apache/commons/io/output/WriterOutputStreamTest.java
src/test/java/org/apache/commons/io/output/WriterOutputStreamTest.java
import java.io.IOException;
import java.io.StringWriter;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Random;
+import org.apache.commons.io.Charsets;
+import org.apache.commons.io.charset.CharsetDecoders;
import org.junit.jupiter.api.Test;
public class WriterOutputStreamTest {
@@ -51,6 +55,16 @@ public void testFlush() throws IOException {
}
}
+ @Test
+ public void testLargeUTF8CharsetWithBufferedWrite() throws IOException {
+ testWithBufferedWrite(LARGE_TEST_STRING, "UTF-8");
+ }
+
+ @Test
+ public void testLargeUTF8CharsetWithSingleByteWrite() throws IOException {
+ testWithSingleByteWrite(LARGE_TEST_STRING, StandardCharsets.UTF_8);
+ }
+
@Test
public void testLargeUTF8WithBufferedWrite() throws IOException {
testWithBufferedWrite(LARGE_TEST_STRING, "UTF-8");
@@ -61,6 +75,21 @@ public void testLargeUTF8WithSingleByteWrite() throws IOException {
testWithSingleByteWrite(LARGE_TEST_STRING, "UTF-8");
}
+ @Test
+ public void testNullCharsetNameWithSingleByteWrite() throws IOException {
+ testWithSingleByteWrite(TEST_STRING, (String) null);
+ }
+
+ @Test
+ public void testNullCharsetWithSingleByteWrite() throws IOException {
+ testWithSingleByteWrite(TEST_STRING, (Charset) null);
+ }
+
+ @Test
+ public void testNullCharsetDecoderWithSingleByteWrite() throws IOException {
+ testWithSingleByteWrite(TEST_STRING, (CharsetDecoder) null);
+ }
+
@Test
public void testUTF16BEWithBufferedWrite() throws IOException {
testWithBufferedWrite(TEST_STRING, "UTF-16BE");
@@ -128,8 +157,30 @@ private void testWithBufferedWrite(final String testString, final String charset
}
+ private void testWithSingleByteWrite(final String testString, final Charset charset) throws IOException {
+ final byte[] bytes = testString.getBytes(Charsets.toCharset(charset));
+ final StringWriter writer = new StringWriter();
+ try (final WriterOutputStream out = new WriterOutputStream(writer, charset)) {
+ for (final byte b : bytes) {
+ out.write(b);
+ }
+ }
+ assertEquals(testString, writer.toString());
+ }
+
+ private void testWithSingleByteWrite(final String testString, final CharsetDecoder charsetDecoder) throws IOException {
+ final byte[] bytes = testString.getBytes(CharsetDecoders.toCharsetDecoder(charsetDecoder).charset());
+ final StringWriter writer = new StringWriter();
+ try (final WriterOutputStream out = new WriterOutputStream(writer, charsetDecoder)) {
+ for (final byte b : bytes) {
+ out.write(b);
+ }
+ }
+ assertEquals(testString, writer.toString());
+ }
+
private void testWithSingleByteWrite(final String testString, final String charsetName) throws IOException {
- final byte[] bytes = testString.getBytes(charsetName);
+ final byte[] bytes = testString.getBytes(Charsets.toCharset(charsetName));
final StringWriter writer = new StringWriter();
try (final WriterOutputStream out = new WriterOutputStream(writer, charsetName)) {
for (final byte b : bytes) {

WriterOutputStream maps null Charset, Charset name, and CharsetEncoder
name to the platform default instead of throwing a NullPointerException.