handle zero and negative thresholds (#587)
diff --git a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java
index 8102eb5..e5b8d5a 100644
--- a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java
@@ -23,9 +23,12 @@
import org.apache.commons.io.function.IOFunction;
/**
- * An output stream which triggers an event when a specified number of bytes of data have been written to it. The event
- * can be used, for example, to throw an exception if a maximum has been reached, or to switch the underlying stream
- * type when the threshold is exceeded.
+ * An output stream which triggers an event on the first write that causes
+ * the total number of bytes written to the stream to exceed a configured threshold,
+ * and every subsequent write. The event
+ * can be used, for example, to throw an exception if a maximum has been reached,
+ * or to switch the underlying stream when the threshold is exceeded.
+ *
* <p>
* This class overrides all {@link OutputStream} methods. However, these overrides ultimately call the corresponding
* methods in the underlying output stream implementation.
@@ -89,6 +92,9 @@
this.threshold = threshold;
this.thresholdConsumer = thresholdConsumer == null ? IOConsumer.noop() : thresholdConsumer;
this.outputStreamGetter = outputStreamGetter == null ? NOOP_OS_GETTER : outputStreamGetter;
+ if (threshold < 0) {
+ thresholdExceeded = true;
+ }
}
/**
@@ -244,6 +250,8 @@
@SuppressWarnings("resource") // the underlying stream is managed by a subclass.
@Override
public void write(final byte[] b, final int off, final int len) throws IOException {
+ // TODO we could write the sub-array up the threshold, fire the event,
+ // and then write the rest so the event is always fired at the precise point.
checkThreshold(len);
// TODO for 4.0: Replace with getOutputStream()
getStream().write(b, off, len);
diff --git a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java
index 080a492..efa67b4 100644
--- a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java
@@ -33,6 +33,29 @@
public class ThresholdingOutputStreamTest {
@Test
+ public void testThresholdLessThanZero() throws IOException {
+ try (final ThresholdingOutputStream out = new ThresholdingOutputStream(-1)) {
+ assertTrue(out.isThresholdExceeded());
+ }
+ }
+
+ @Test
+ public void testThresholdZero() throws IOException {
+ final AtomicBoolean reached = new AtomicBoolean(false);
+ try (final ThresholdingOutputStream out = new ThresholdingOutputStream(0) {
+ @Override
+ protected void thresholdReached() throws IOException {
+ reached.set(true);
+ }
+ }) {
+ assertFalse(out.isThresholdExceeded());
+ out.write(89);
+ assertTrue(reached.get());
+ assertTrue(out.isThresholdExceeded());
+ }
+ }
+
+ @Test
public void testSetByteCount_OutputStream() throws Exception {
final AtomicBoolean reached = new AtomicBoolean(false);
try (ThresholdingOutputStream tos = new ThresholdingOutputStream(3) {