Skip to content

Commit 93228b3

Browse files
author
Gary Gregory
committed
Add UncheckedFilterInputStream.
1 parent 61c1b0d commit 93228b3

3 files changed

Lines changed: 293 additions & 0 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ The <action> type attribute can be add,update,fix,remove.
6666
<action dev="ggregory" type="add" due-to="Gary Gregory">
6767
Add StringInputStream.
6868
</action>
69+
<action dev="ggregory" type="add" due-to="Gary Gregory">
70+
Add UncheckedFilterInputStream.
71+
</action>
6972
<!-- UPDATE -->
7073
<action dev="ggregory" type="update" due-to="Dependabot">
7174
Bump Maven Javadoc plugin from 3.2.0 to 3.3.0.
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.commons.io.input;
20+
21+
import java.io.BufferedReader;
22+
import java.io.FilterInputStream;
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
import java.io.UncheckedIOException;
26+
27+
/**
28+
* A {@link BufferedReader} that throws {@link UncheckedIOException} instead of {@link IOException}.
29+
*
30+
* @see BufferedReader
31+
* @see IOException
32+
* @see UncheckedIOException
33+
* @since 2.12.0
34+
*/
35+
public class UncheckedFilterInputStream extends FilterInputStream {
36+
37+
/**
38+
* Creates a {@code UncheckedFilterInputStream}.
39+
*
40+
* @param inputStream the underlying input stream, or {@code null} if this instance is to be created without an
41+
* underlying stream.
42+
* @return a new UncheckedFilterInputStream.
43+
*/
44+
public static UncheckedFilterInputStream on(final InputStream inputStream) {
45+
return new UncheckedFilterInputStream(inputStream);
46+
}
47+
48+
/**
49+
* Creates a {@code UncheckedFilterInputStream}.
50+
*
51+
* @param inputStream the underlying input stream, or {@code null} if this instance is to be created without an
52+
* underlying stream.
53+
*/
54+
public UncheckedFilterInputStream(final InputStream inputStream) {
55+
super(inputStream);
56+
}
57+
58+
/**
59+
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
60+
*/
61+
@Override
62+
public int available() throws UncheckedIOException {
63+
try {
64+
return super.available();
65+
} catch (final IOException e) {
66+
throw uncheck(e);
67+
}
68+
}
69+
70+
/**
71+
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
72+
*/
73+
@Override
74+
public void close() throws UncheckedIOException {
75+
try {
76+
super.close();
77+
} catch (final IOException e) {
78+
throw uncheck(e);
79+
}
80+
}
81+
82+
/**
83+
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
84+
*/
85+
@Override
86+
public int read() throws UncheckedIOException {
87+
try {
88+
return super.read();
89+
} catch (final IOException e) {
90+
throw uncheck(e);
91+
}
92+
}
93+
94+
/**
95+
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
96+
*/
97+
@Override
98+
public int read(final byte[] b) throws UncheckedIOException {
99+
try {
100+
return super.read(b);
101+
} catch (final IOException e) {
102+
throw uncheck(e);
103+
}
104+
}
105+
106+
/**
107+
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
108+
*/
109+
@Override
110+
public int read(final byte[] b, final int off, final int len) throws UncheckedIOException {
111+
try {
112+
return super.read(b, off, len);
113+
} catch (final IOException e) {
114+
throw uncheck(e);
115+
}
116+
}
117+
118+
/**
119+
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
120+
*/
121+
@Override
122+
public synchronized void reset() throws UncheckedIOException {
123+
try {
124+
super.reset();
125+
} catch (final IOException e) {
126+
throw uncheck(e);
127+
}
128+
}
129+
130+
/**
131+
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
132+
*/
133+
@Override
134+
public long skip(final long n) throws UncheckedIOException {
135+
try {
136+
return super.skip(n);
137+
} catch (final IOException e) {
138+
throw uncheck(e);
139+
}
140+
}
141+
142+
private UncheckedIOException uncheck(final IOException e) {
143+
return new UncheckedIOException(e);
144+
}
145+
146+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.io.input;
19+
20+
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertThrows;
22+
23+
import java.io.BufferedInputStream;
24+
import java.io.IOException;
25+
import java.io.UncheckedIOException;
26+
27+
import org.apache.commons.io.IOUtils;
28+
import org.junit.jupiter.api.BeforeEach;
29+
import org.junit.jupiter.api.Test;
30+
31+
/**
32+
* Tests {@link UncheckedFilterInputStream}.
33+
*/
34+
public class UncheckedFilterInputStreamTest {
35+
36+
private UncheckedFilterInputStream stringInputStream;
37+
private UncheckedFilterInputStream brokenInputStream;
38+
private IOException exception = new IOException("test exception");
39+
40+
@SuppressWarnings("resource")
41+
@BeforeEach
42+
public void beforeEach() {
43+
stringInputStream = UncheckedFilterInputStream.on(new BufferedInputStream(new StringInputStream("01")));
44+
exception = new IOException("test exception");
45+
brokenInputStream = UncheckedFilterInputStream.on(new BrokenInputStream(exception));
46+
}
47+
48+
@Test
49+
public void testClose() {
50+
stringInputStream.close();
51+
assertThrows(UncheckedIOException.class, () -> brokenInputStream.read());
52+
}
53+
54+
@Test
55+
public void testCloseThrows() {
56+
assertEquals(exception, assertThrows(UncheckedIOException.class, () -> brokenInputStream.close()).getCause());
57+
}
58+
59+
@Test
60+
public void testMarkReset() {
61+
stringInputStream.mark(10);
62+
final int c = stringInputStream.read();
63+
stringInputStream.reset();
64+
assertEquals(c, stringInputStream.read());
65+
}
66+
67+
@Test
68+
public void testRead() {
69+
try (final UncheckedFilterInputStream uncheckedReader = UncheckedFilterInputStream.on(stringInputStream)) {
70+
assertEquals('0', uncheckedReader.read());
71+
assertEquals('1', uncheckedReader.read());
72+
assertEquals(IOUtils.EOF, uncheckedReader.read());
73+
assertEquals(IOUtils.EOF, uncheckedReader.read());
74+
}
75+
}
76+
77+
@Test
78+
public void testReadByteArray() {
79+
try (final UncheckedFilterInputStream uncheckedReader = UncheckedFilterInputStream.on(stringInputStream)) {
80+
final byte[] array = new byte[1];
81+
assertEquals(1, uncheckedReader.read(array));
82+
assertEquals('0', array[0]);
83+
array[0] = 0;
84+
assertEquals(1, uncheckedReader.read(array));
85+
assertEquals('1', array[0]);
86+
array[0] = 0;
87+
assertEquals(IOUtils.EOF, uncheckedReader.read(array));
88+
assertEquals(0, array[0]);
89+
assertEquals(IOUtils.EOF, uncheckedReader.read(array));
90+
assertEquals(0, array[0]);
91+
}
92+
}
93+
94+
@Test
95+
public void testReadByteArrayIndexed() {
96+
try (final UncheckedFilterInputStream uncheckedReader = UncheckedFilterInputStream.on(stringInputStream)) {
97+
final byte[] array = new byte[1];
98+
assertEquals(1, uncheckedReader.read(array, 0, 1));
99+
assertEquals('0', array[0]);
100+
array[0] = 0;
101+
assertEquals(1, uncheckedReader.read(array, 0, 1));
102+
assertEquals('1', array[0]);
103+
array[0] = 0;
104+
assertEquals(IOUtils.EOF, uncheckedReader.read(array, 0, 1));
105+
assertEquals(0, array[0]);
106+
assertEquals(IOUtils.EOF, uncheckedReader.read(array, 0, 1));
107+
assertEquals(0, array[0]);
108+
}
109+
}
110+
111+
@Test
112+
public void testReadByteArrayIndexedThrows() {
113+
assertEquals(exception, assertThrows(UncheckedIOException.class, () -> brokenInputStream.read(new byte[1], 0, 1)).getCause());
114+
}
115+
116+
@Test
117+
public void testReadByteArrayThrows() {
118+
assertEquals(exception, assertThrows(UncheckedIOException.class, () -> brokenInputStream.read(new byte[1])).getCause());
119+
}
120+
121+
@Test
122+
public void testReadThrows() {
123+
assertEquals(exception, assertThrows(UncheckedIOException.class, () -> brokenInputStream.read()).getCause());
124+
}
125+
126+
@Test
127+
public void testResetThrows() {
128+
try (UncheckedFilterInputStream closedReader = UncheckedFilterInputStream.on(ClosedInputStream.CLOSED_INPUT_STREAM)) {
129+
closedReader.close();
130+
assertThrows(UncheckedIOException.class, () -> brokenInputStream.reset());
131+
}
132+
}
133+
134+
@Test
135+
public void testSkip() {
136+
assertEquals(1, stringInputStream.skip(1));
137+
}
138+
139+
@Test
140+
public void testSkipThrows() {
141+
assertEquals(exception, assertThrows(UncheckedIOException.class, () -> brokenInputStream.skip(1)).getCause());
142+
}
143+
144+
}

0 commit comments

Comments
 (0)