Skip to content

Commit 55aa76a

Browse files
committed
Add support to ChecksumInputStream for setting a consumer for
ProxyInputStream.afterRead(int)
1 parent f48c5a6 commit 55aa76a

4 files changed

Lines changed: 52 additions & 16 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ The <action> type attribute can be add,update,fix,remove.
6969
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to AutoCloseInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7070
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to BOMInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7171
<action dev="ggregory" type="add" issue="IO-861" due-to="Gary Gregory">Add support to BoundedInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
72+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ChecksumInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7273
<!-- UPDATE -->
7374
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 74 to 78 #670, #676, #679, #688.</action>
7475
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump commons.bytebuddy.version from 1.15.1 to 1.15.10 #672, #673, #685, #686, #694, #696, #698.</action>

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

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
import java.util.zip.CheckedInputStream;
2525
import java.util.zip.Checksum;
2626

27-
import org.apache.commons.io.build.AbstractStreamBuilder;
28-
2927
/**
3028
* Automatically verifies a {@link Checksum} value once the stream is exhausted or the count threshold is reached.
3129
* <p>
@@ -98,7 +96,7 @@ public final class ChecksumInputStream extends CountingInputStream {
9896
* @see #get()
9997
*/
10098
// @formatter:on
101-
public static class Builder extends AbstractStreamBuilder<ChecksumInputStream, Builder> {
99+
public static class Builder extends AbstractBuilder<ChecksumInputStream, Builder> {
102100

103101
/**
104102
* There is no default {@link Checksum}, you MUST provide one. This avoids any issue with a default {@link Checksum} being proven deficient or insecure
@@ -141,10 +139,9 @@ public static class Builder extends AbstractStreamBuilder<ChecksumInputStream, B
141139
* @throws IOException if an I/O error occurs.
142140
* @see #getInputStream()
143141
*/
144-
@SuppressWarnings("resource")
145142
@Override
146143
public ChecksumInputStream get() throws IOException {
147-
return new ChecksumInputStream(getInputStream(), checksum, expectedChecksumValue, countThreshold);
144+
return new ChecksumInputStream(this);
148145
}
149146

150147
/**
@@ -211,17 +208,13 @@ public static Builder builder() {
211208
/**
212209
* Constructs a new instance.
213210
*
214-
* @param in the stream to wrap.
215-
* @param checksum a Checksum implementation.
216-
* @param expectedChecksumValue the expected checksum.
217-
* @param countThreshold the count threshold to limit how much input is consumed, a negative number means the
218-
* threshold is unbound.
211+
* @param builder build parameters.
219212
*/
220-
private ChecksumInputStream(final InputStream in, final Checksum checksum, final long expectedChecksumValue,
221-
final long countThreshold) {
222-
super(new CheckedInputStream(in, Objects.requireNonNull(checksum, "checksum")));
223-
this.countThreshold = countThreshold;
224-
this.expectedChecksumValue = expectedChecksumValue;
213+
@SuppressWarnings("resource")
214+
private ChecksumInputStream(final Builder builder) throws IOException {
215+
super(new CheckedInputStream(builder.getInputStream(), Objects.requireNonNull(builder.checksum, "builder.checksum")), builder);
216+
this.countThreshold = builder.countThreshold;
217+
this.expectedChecksumValue = builder.expectedChecksumValue;
225218
}
226219

227220
@Override

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
@Deprecated
3434
public class CountingInputStream extends ProxyInputStream {
3535

36-
/** The count of bytes that have passed. */
36+
/** The count of bytes read. */
3737
private long count;
3838

3939
/**
@@ -45,6 +45,14 @@ public CountingInputStream(final InputStream in) {
4545
super(in);
4646
}
4747

48+
CountingInputStream(final InputStream in, final ProxyInputStream.AbstractBuilder<?, ?> builder) {
49+
super(in, builder);
50+
}
51+
52+
CountingInputStream(final ProxyInputStream.AbstractBuilder<?, ?> builder) throws IOException {
53+
super(builder);
54+
}
55+
4856
/**
4957
* Adds the number of read bytes to the count.
5058
*
@@ -57,6 +65,7 @@ protected synchronized void afterRead(final int n) throws IOException {
5765
if (n != EOF) {
5866
count += n;
5967
}
68+
super.afterRead(n);
6069
}
6170

6271
/**

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,18 @@
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.assertThrows;
22+
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
2223
import static org.junit.jupiter.api.Assertions.assertTrue;
2324

2425
import java.io.ByteArrayInputStream;
2526
import java.io.IOException;
2627
import java.io.InputStream;
28+
import java.util.concurrent.atomic.AtomicBoolean;
2729
import java.util.zip.Adler32;
2830
import java.util.zip.CRC32;
2931

3032
import org.apache.commons.io.IOUtils;
33+
import org.apache.commons.io.test.CustomIOException;
3134
import org.junit.jupiter.api.Test;
3235

3336
/**
@@ -39,6 +42,36 @@ private ChecksumInputStream createInputStream() throws IOException {
3942
return ChecksumInputStream.builder().setCharSequence("Hi").setChecksum(new CRC32()).get();
4043
}
4144

45+
@Test
46+
public void testAfterReadConsumer() throws Exception {
47+
final AtomicBoolean boolRef = new AtomicBoolean();
48+
// @formatter:off
49+
try (InputStream bounded = ChecksumInputStream.builder()
50+
.setCharSequence("Hi")
51+
.setChecksum(new CRC32())
52+
.setExpectedChecksumValue(1293356558)
53+
.setAfterRead(i -> boolRef.set(true))
54+
.get()) {
55+
IOUtils.consume(bounded);
56+
}
57+
// @formatter:on
58+
assertTrue(boolRef.get());
59+
// Throwing
60+
final String message = "test exception message";
61+
// @formatter:off
62+
try (InputStream bounded = ChecksumInputStream.builder()
63+
.setCharSequence("Hi")
64+
.setChecksum(new CRC32())
65+
.setExpectedChecksumValue(1293356558)
66+
.setAfterRead(i -> {
67+
throw new CustomIOException(message);
68+
})
69+
.get()) {
70+
assertEquals(message, assertThrowsExactly(CustomIOException.class, () -> IOUtils.consume(bounded)).getMessage());
71+
}
72+
// @formatter:on
73+
}
74+
4275
@SuppressWarnings("resource")
4376
@Test
4477
public void testAvailableAfterClose() throws Exception {

0 commit comments

Comments
 (0)