This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
commit 48be3f94dbdf792abc67d16e23fa551f15dd28a5 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Sun Jul 7 17:27:43 2024 -0400 CircularInputStream.available() should return 0 when the stream is closed --- src/changes/changes.xml | 1 + .../commons/io/input/CircularInputStream.java | 12 +++++++++ .../commons/io/input/CircularInputStreamTest.java | 31 +++++++++++++++++++--- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index a7ab44abc..2cea2bae5 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -66,6 +66,7 @@ The <action> type attribute can be add,update,fix,remove. <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> <action dev="ggregory" type="add" due-to="Gary Gregory">CharSequenceInputStream.available() should return 0 after the stream is closed.</action> <action dev="ggregory" type="add" due-to="Gary Gregory">BoundedInputStream.available() should return 0 when the stream is closed.</action> + <action dev="ggregory" type="add" due-to="Gary Gregory">CircularInputStream.available() should return 0 when the stream is closed.</action> <!-- UPDATE --> <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> <action dev="ggregory" type="update" due-to="Dependabot">Bump tests commons-codec:commons-codec from 1.16.1 to 1.17.0.</action> diff --git a/src/main/java/org/apache/commons/io/input/CircularInputStream.java b/src/main/java/org/apache/commons/io/input/CircularInputStream.java index 24619e652..1376e009d 100644 --- a/src/main/java/org/apache/commons/io/input/CircularInputStream.java +++ b/src/main/java/org/apache/commons/io/input/CircularInputStream.java @@ -54,6 +54,7 @@ public class CircularInputStream extends InputStream { private int position = IOUtils.EOF; private final byte[] repeatedContent; private final long targetByteCount; + private boolean closed; /** * Constructs an instance from the specified array of bytes. @@ -69,6 +70,17 @@ public class CircularInputStream extends InputStream { this.targetByteCount = targetByteCount; } + @Override + public int available() throws IOException { + return closed ? 0 : targetByteCount <= Integer.MAX_VALUE ? (int) targetByteCount : Integer.MAX_VALUE; + } + + @Override + public void close() throws IOException { + closed = true; + byteCount = targetByteCount; + } + @Override public int read() { if (targetByteCount >= 0) { diff --git a/src/test/java/org/apache/commons/io/input/CircularInputStreamTest.java b/src/test/java/org/apache/commons/io/input/CircularInputStreamTest.java index db8bb37b5..50b975a33 100644 --- a/src/test/java/org/apache/commons/io/input/CircularInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/CircularInputStreamTest.java @@ -19,6 +19,7 @@ package org.apache.commons.io.input; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.io.InputStream; @@ -32,12 +33,37 @@ import org.junit.jupiter.api.Test; */ public class CircularInputStreamTest { + @SuppressWarnings("resource") + @Test + public void testAvailable() throws Exception { + final InputStream shadow; + try (InputStream in = createInputStream(new byte[] { 1, 2 }, 1)) { + assertTrue(in.available() > 0); + shadow = in; + } + assertEquals(0, shadow.available()); + } + + @SuppressWarnings("resource") + @Test + public void testReadAfterClose() throws Exception { + final InputStream shadow; + try (InputStream in = createInputStream(new byte[] { 1, 2 }, 4)) { + assertTrue(in.available() > 0); + assertEquals(1, in.read()); + assertEquals(2, in.read()); + assertEquals(1, in.read()); + shadow = in; + } + assertEquals(0, shadow.available()); + assertEquals(IOUtils.EOF, shadow.read()); + } + private void assertStreamOutput(final byte[] toCycle, final byte[] expected) throws IOException { final byte[] actual = new byte[expected.length]; try (InputStream infStream = createInputStream(toCycle, -1)) { final int actualReadBytes = infStream.read(actual); - assertArrayEquals(expected, actual); assertEquals(expected.length, actualReadBytes); } @@ -83,7 +109,6 @@ public class CircularInputStreamTest { public void testCycleBytes() throws IOException { final byte[] input = { 1, 2 }; final byte[] expected = { 1, 2, 1, 2, 1 }; - assertStreamOutput(input, expected); } @@ -101,9 +126,7 @@ public class CircularInputStreamTest { contentToCycle[i] = value == IOUtils.EOF ? 0 : value; value++; } - final byte[] expectedOutput = Arrays.copyOf(contentToCycle, size); - assertStreamOutput(contentToCycle, expectedOutput); }