Skip to content

Commit 117e219

Browse files
committed
Add CharSequenceInputStream.Builder.setCharsetEncoder(CharsetEncoder)
Add CharsetEncoders.toCharsetEncoder(CharsetEncoder, Supplier<CharsetEncoder>)
1 parent 8cc157e commit 117e219

5 files changed

Lines changed: 109 additions & 19 deletions

File tree

src/changes/changes.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ The <action> type attribute can be add,update,fix,remove.
9999
Add AbstractOrigin.size().
100100
</action>
101101
<action dev="ggregory" type="add" due-to="Gary Gregory">
102-
PathUtils.EMPTY_FILE_ATTRIBUTE_ARRAY.
102+
Add PathUtils.EMPTY_FILE_ATTRIBUTE_ARRAY.
103+
</action>
104+
<action dev="ggregory" type="add" due-to="Gary Gregory">
105+
Add CharSequenceInputStream.Builder.setCharsetEncoder(CharsetEncoder).
106+
</action>
107+
<action dev="ggregory" type="add" due-to="Gary Gregory">
108+
Add CharsetEncoders.toCharsetEncoder(CharsetEncoder, Supplier&lt;CharsetEncoder&gt;).
103109
</action>
104110
<!-- UPDATE -->
105111
<action dev="ggregory" type="update" due-to="Gary Gregory, Dependabot">

src/main/java/org/apache/commons/io/charset/CharsetEncoders.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.nio.charset.Charset;
2121
import java.nio.charset.CharsetEncoder;
22+
import java.util.function.Supplier;
2223

2324
/**
2425
* Works with {@link CharsetEncoder}.
@@ -34,7 +35,19 @@ public final class CharsetEncoders {
3435
* @return the given non-null CharsetEncoder or a new default CharsetEncoder.
3536
*/
3637
public static CharsetEncoder toCharsetEncoder(final CharsetEncoder charsetEncoder) {
37-
return charsetEncoder != null ? charsetEncoder : Charset.defaultCharset().newEncoder();
38+
return toCharsetEncoder(charsetEncoder, () -> Charset.defaultCharset().newEncoder());
39+
}
40+
41+
/**
42+
* Returns the given non-null CharsetEncoder or a new default CharsetEncoder.
43+
*
44+
* @param charsetEncoder The CharsetEncoder to test.
45+
* @param defaultSupplier The CharsetEncoder supplier to get when charsetEncoder is null.
46+
* @return the given non-null CharsetEncoder or a new default CharsetEncoder.
47+
* @since 2.13.0
48+
*/
49+
public static CharsetEncoder toCharsetEncoder(final CharsetEncoder charsetEncoder, final Supplier<CharsetEncoder> defaultSupplier) {
50+
return charsetEncoder != null ? charsetEncoder : defaultSupplier.get();
3851
}
3952

4053
/** No instances. */

src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.commons.io.Charsets;
3434
import org.apache.commons.io.IOUtils;
3535
import org.apache.commons.io.build.AbstractStreamBuilder;
36+
import org.apache.commons.io.charset.CharsetEncoders;
3637
import org.apache.commons.io.function.Uncheck;
3738

3839
/**
@@ -50,19 +51,31 @@ public class CharSequenceInputStream extends InputStream {
5051
* <p>
5152
* For example:
5253
* </p>
53-
*
54+
* <h2>Using a Charset</h2>
55+
* <pre>{@code
56+
* CharSequenceInputStream s = CharSequenceInputStream.builder()
57+
* .setBufferSize(8192)
58+
* .setCharSequence("String")
59+
* .setCharset(Charset.defaultCharset())
60+
* .get();}
61+
* </pre>
62+
* <h2>Using a CharsetEncoder</h2>
5463
* <pre>{@code
5564
* CharSequenceInputStream s = CharSequenceInputStream.builder()
5665
* .setBufferSize(8192)
5766
* .setCharSequence("String")
58-
* .setCharsetEncoder(Charset.defaultCharset())
67+
* .setCharsetEncoder(Charset.defaultCharset().newEncoder()
68+
* .onMalformedInput(CodingErrorAction.REPLACE)
69+
* .onUnmappableCharacter(CodingErrorAction.REPLACE))
5970
* .get();}
6071
* </pre>
6172
*
6273
* @since 2.13.0
6374
*/
6475
public static class Builder extends AbstractStreamBuilder<CharSequenceInputStream, Builder> {
6576

77+
private CharsetEncoder charsetEncoder = newEncoder(getCharset());
78+
6679
/**
6780
* Constructs a new instance.
6881
* <p>
@@ -74,7 +87,31 @@ public static class Builder extends AbstractStreamBuilder<CharSequenceInputStrea
7487
*/
7588
@Override
7689
public CharSequenceInputStream get() {
77-
return Uncheck.get(() -> new CharSequenceInputStream(getCharSequence(), getCharset(), getBufferSize()));
90+
return Uncheck.get(() -> new CharSequenceInputStream(getCharSequence(), getBufferSize(), charsetEncoder));
91+
}
92+
93+
CharsetEncoder getCharsetEncoder() {
94+
return charsetEncoder;
95+
}
96+
97+
@Override
98+
public Builder setCharset(final Charset charset) {
99+
super.setCharset(charset);
100+
charsetEncoder = newEncoder(getCharset());
101+
return this;
102+
}
103+
104+
/**
105+
* Sets the charset encoder. Assumes that the caller has configured the encoder.
106+
*
107+
* @param newEncoder the charset encoder.
108+
* @return this
109+
* @since 2.13.0
110+
*/
111+
public Builder setCharsetEncoder(final CharsetEncoder newEncoder) {
112+
charsetEncoder = CharsetEncoders.toCharsetEncoder(newEncoder, () -> newEncoder(getCharsetDefault()));
113+
super.setCharset(charsetEncoder.charset());
114+
return this;
78115
}
79116

80117
}
@@ -91,12 +128,19 @@ public static Builder builder() {
91128
return new Builder();
92129
}
93130

94-
private final CharsetEncoder charsetEncoder;
95-
private final CharBuffer cBuf;
96-
private final ByteBuffer bBuf;
131+
private static CharsetEncoder newEncoder(final Charset charset) {
132+
// @formatter:off
133+
return Charsets.toCharset(charset).newEncoder()
134+
.onMalformedInput(CodingErrorAction.REPLACE)
135+
.onUnmappableCharacter(CodingErrorAction.REPLACE);
136+
// @formatter:on
137+
}
97138

98-
private int cBufMark; // position in cBuf
139+
private final ByteBuffer bBuf;
99140
private int bBufMark; // position in bBuf
141+
private final CharBuffer cBuf;
142+
private int cBufMark; // position in cBuf
143+
private final CharsetEncoder charsetEncoder;
100144

101145
/**
102146
* Constructs a new instance with a buffer size of {@link IOUtils#DEFAULT_BUFFER_SIZE}.
@@ -123,10 +167,12 @@ public CharSequenceInputStream(final CharSequence cs, final Charset charset) {
123167
@Deprecated
124168
public CharSequenceInputStream(final CharSequence cs, final Charset charset, final int bufferSize) {
125169
// @formatter:off
126-
this.charsetEncoder = Charsets.toCharset(charset).newEncoder()
127-
.onMalformedInput(CodingErrorAction.REPLACE)
128-
.onUnmappableCharacter(CodingErrorAction.REPLACE);
170+
this(cs, bufferSize, newEncoder(charset));
129171
// @formatter:on
172+
}
173+
174+
private CharSequenceInputStream(final CharSequence cs, final int bufferSize, final CharsetEncoder charsetEncoder) {
175+
this.charsetEncoder = charsetEncoder;
130176
// Ensure that buffer is long enough to hold a complete character
131177
this.bBuf = ByteBuffer.allocate(ReaderInputStream.checkMinBufferSize(charsetEncoder, bufferSize));
132178
this.bBuf.flip();

src/main/java/org/apache/commons/io/input/ReaderInputStream.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public class ReaderInputStream extends InputStream {
100100
*/
101101
public static class Builder extends AbstractStreamBuilder<ReaderInputStream, Builder> {
102102

103-
private CharsetEncoder charsetEncoder = super.getCharset().newEncoder();
103+
private CharsetEncoder charsetEncoder = newEncoder(getCharset());
104104

105105
/**
106106
* Constructs a new instance.
@@ -130,24 +130,32 @@ CharsetEncoder getCharsetEncoder() {
130130
@Override
131131
public Builder setCharset(final Charset charset) {
132132
super.setCharset(charset);
133-
charsetEncoder = getCharset().newEncoder();
133+
charsetEncoder = newEncoder(getCharset());
134134
return this;
135135
}
136136

137137
/**
138-
* Sets the charset encoder.
138+
* Sets the charset encoder. Assumes that the caller has configured the encoder.
139139
*
140-
* @param charsetEncoder the charset encoder, null resets to a default encoder.
140+
* @param newEncoder the charset encoder, null resets to a default encoder.
141141
* @return this
142142
*/
143-
public Builder setCharsetEncoder(final CharsetEncoder charsetEncoder) {
144-
this.charsetEncoder = CharsetEncoders.toCharsetEncoder(charsetEncoder);
145-
super.setCharset(this.charsetEncoder.charset());
143+
public Builder setCharsetEncoder(final CharsetEncoder newEncoder) {
144+
charsetEncoder = CharsetEncoders.toCharsetEncoder(newEncoder, () -> newEncoder(getCharsetDefault()));
145+
super.setCharset(charsetEncoder.charset());
146146
return this;
147147
}
148148

149149
}
150150

151+
private static CharsetEncoder newEncoder(final Charset charset) {
152+
// @formatter:off
153+
return Charsets.toCharset(charset).newEncoder()
154+
.onMalformedInput(CodingErrorAction.REPLACE)
155+
.onUnmappableCharacter(CodingErrorAction.REPLACE);
156+
// @formatter:on
157+
}
158+
151159
/**
152160
* Constructs a new {@link Builder}.
153161
*

src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
2020
import static org.junit.jupiter.api.Assertions.assertEquals;
2121
import static org.junit.jupiter.api.Assertions.assertNotEquals;
22+
import static org.junit.jupiter.api.Assertions.assertNotNull;
2223
import static org.junit.jupiter.api.Assertions.assertTrue;
2324
import static org.junit.jupiter.api.Assertions.fail;
2425

2526
import java.io.IOException;
2627
import java.io.InputStream;
28+
import java.io.StringReader;
2729
import java.nio.charset.Charset;
2830
import java.nio.charset.StandardCharsets;
2931
import java.util.Random;
@@ -436,6 +438,21 @@ private void testSingleByteRead(final String testString, final String charsetNam
436438
}
437439
}
438440

441+
@Test
442+
public void testResetCharset() {
443+
assertNotNull(CharSequenceInputStream.builder().setReader(new StringReader("\uD800")).setCharset((Charset) null).getCharset());
444+
}
445+
446+
@Test
447+
public void testResetCharsetEncoder() {
448+
assertNotNull(CharSequenceInputStream.builder().setReader(new StringReader("\uD800")).setCharsetEncoder(null).getCharsetEncoder());
449+
}
450+
451+
@Test
452+
public void testResetCharsetName() {
453+
assertNotNull(CharSequenceInputStream.builder().setReader(new StringReader("\uD800")).setCharset((String) null).getCharset());
454+
}
455+
439456
@Test
440457
public void testSingleByteRead_RequiredCharsets() throws IOException {
441458
for (final String csName : getRequiredCharsetNames()) {

0 commit comments

Comments
 (0)