Skip to content

Commit 48be3f9

Browse files
committed
CircularInputStream.available() should return 0 when the stream is
closed
1 parent 907fc90 commit 48be3f9

3 files changed

Lines changed: 40 additions & 4 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ The <action> type attribute can be add,update,fix,remove.
6666
<action dev="ggregory" type="add" due-to="Gary Gregory">BufferedFileChannelInputStream.available() should return 0 when the stream is closed instead of throwing an exception.</action>
6767
<action dev="ggregory" type="add" due-to="Gary Gregory">CharSequenceInputStream.available() should return 0 after the stream is closed.</action>
6868
<action dev="ggregory" type="add" due-to="Gary Gregory">BoundedInputStream.available() should return 0 when the stream is closed.</action>
69+
<action dev="ggregory" type="add" due-to="Gary Gregory">CircularInputStream.available() should return 0 when the stream is closed.</action>
6970
<!-- UPDATE -->
7071
<action dev="ggregory" type="update" due-to="Dependabot">Bump tests commons.bytebuddy.version from 1.14.13 to 1.14.17 #615, #621, #631, #635.</action>
7172
<action dev="ggregory" type="update" due-to="Dependabot">Bump tests commons-codec:commons-codec from 1.16.1 to 1.17.0.</action>

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ private static byte[] validate(final byte[] repeatContent) {
5454
private int position = IOUtils.EOF;
5555
private final byte[] repeatedContent;
5656
private final long targetByteCount;
57+
private boolean closed;
5758

5859
/**
5960
* Constructs an instance from the specified array of bytes.
@@ -69,6 +70,17 @@ public CircularInputStream(final byte[] repeatContent, final long targetByteCoun
6970
this.targetByteCount = targetByteCount;
7071
}
7172

73+
@Override
74+
public int available() throws IOException {
75+
return closed ? 0 : targetByteCount <= Integer.MAX_VALUE ? (int) targetByteCount : Integer.MAX_VALUE;
76+
}
77+
78+
@Override
79+
public void close() throws IOException {
80+
closed = true;
81+
byteCount = targetByteCount;
82+
}
83+
7284
@Override
7385
public int read() {
7486
if (targetByteCount >= 0) {

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
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.assertTrue;
2223

2324
import java.io.IOException;
2425
import java.io.InputStream;
@@ -32,12 +33,37 @@
3233
*/
3334
public class CircularInputStreamTest {
3435

36+
@SuppressWarnings("resource")
37+
@Test
38+
public void testAvailable() throws Exception {
39+
final InputStream shadow;
40+
try (InputStream in = createInputStream(new byte[] { 1, 2 }, 1)) {
41+
assertTrue(in.available() > 0);
42+
shadow = in;
43+
}
44+
assertEquals(0, shadow.available());
45+
}
46+
47+
@SuppressWarnings("resource")
48+
@Test
49+
public void testReadAfterClose() throws Exception {
50+
final InputStream shadow;
51+
try (InputStream in = createInputStream(new byte[] { 1, 2 }, 4)) {
52+
assertTrue(in.available() > 0);
53+
assertEquals(1, in.read());
54+
assertEquals(2, in.read());
55+
assertEquals(1, in.read());
56+
shadow = in;
57+
}
58+
assertEquals(0, shadow.available());
59+
assertEquals(IOUtils.EOF, shadow.read());
60+
}
61+
3562
private void assertStreamOutput(final byte[] toCycle, final byte[] expected) throws IOException {
3663
final byte[] actual = new byte[expected.length];
3764

3865
try (InputStream infStream = createInputStream(toCycle, -1)) {
3966
final int actualReadBytes = infStream.read(actual);
40-
4167
assertArrayEquals(expected, actual);
4268
assertEquals(expected.length, actualReadBytes);
4369
}
@@ -83,7 +109,6 @@ public void testCount1InputSize1() throws IOException {
83109
public void testCycleBytes() throws IOException {
84110
final byte[] input = { 1, 2 };
85111
final byte[] expected = { 1, 2, 1, 2, 1 };
86-
87112
assertStreamOutput(input, expected);
88113
}
89114

@@ -101,9 +126,7 @@ public void testWholeRangeOfBytes() throws IOException {
101126
contentToCycle[i] = value == IOUtils.EOF ? 0 : value;
102127
value++;
103128
}
104-
105129
final byte[] expectedOutput = Arrays.copyOf(contentToCycle, size);
106-
107130
assertStreamOutput(contentToCycle, expectedOutput);
108131
}
109132

0 commit comments

Comments
 (0)