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);
     }
 

Reply via email to