1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.compress.utils;
19
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.EOFException;
28 import java.io.FilterInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.nio.ByteBuffer;
33 import java.nio.channels.ReadableByteChannel;
34 import java.nio.charset.StandardCharsets;
35
36 import org.apache.commons.io.input.NullInputStream;
37 import org.apache.commons.io.output.NullOutputStream;
38 import org.junit.jupiter.api.Test;
39
40 public class IOUtilsTest {
41
42 private interface StreamWrapper {
43 InputStream wrap(InputStream toWrap);
44 }
45
46 private static void readFully(final byte[] source, final ByteBuffer b) throws IOException {
47 try (SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(source)) {
48 IOUtils.readFully(channel, b);
49 }
50 }
51
52 private void skip(final StreamWrapper wrapper) throws Exception {
53 final ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
54 try (InputStream sut = wrapper.wrap(in)) {
55 assertEquals(10, IOUtils.skip(sut, 10));
56 assertEquals(11, sut.read());
57 }
58 }
59
60 @Test
61 public void testCopy_inputStreamToOutputStream_IO84() throws Exception {
62 final long size = (long) Integer.MAX_VALUE + (long) 1;
63 final InputStream in = new NullInputStream(size);
64 final OutputStream out = NullOutputStream.INSTANCE;
65
66 assertEquals(-1, IOUtils.copy(in, out));
67
68 in.close();
69 }
70
71 @Test
72 public void testCopy_inputStreamToOutputStream_nullIn() {
73 final OutputStream out = new ByteArrayOutputStream();
74 assertThrows(NullPointerException.class, () -> IOUtils.copy((InputStream) null, out));
75 }
76
77 @Test
78 public void testCopy_inputStreamToOutputStream_nullOut() {
79 final InputStream in = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 });
80 assertThrows(NullPointerException.class, () -> IOUtils.copy(in, (OutputStream) null));
81 }
82
83 @Test
84 public void testCopyRangeDoesntCopyMoreThanAskedFor() throws IOException {
85 try (ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5 });
86 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
87 assertEquals(3, IOUtils.copyRange(in, 3, out));
88 out.close();
89 assertArrayEquals(new byte[] { 1, 2, 3 }, out.toByteArray());
90 }
91 }
92
93 @Test
94 public void testCopyRangeStopsIfThereIsNothingToCopyAnymore() throws IOException {
95 try (ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5 });
96 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
97 assertEquals(5, IOUtils.copyRange(in, 10, out));
98 out.close();
99 assertArrayEquals(new byte[] { 1, 2, 3, 4, 5 }, out.toByteArray());
100 }
101 }
102
103 @Test
104 public void testCopyRangeThrowsOnZeroBufferSize() {
105 assertThrows(IllegalArgumentException.class,
106 () -> IOUtils.copyRange(new ByteArrayInputStream(ByteUtils.EMPTY_BYTE_ARRAY), 5, new ByteArrayOutputStream(), 0));
107 }
108
109 @Test
110 public void testCopyThrowsOnZeroBufferSize() throws IOException {
111 assertEquals(0, IOUtils.copy(new ByteArrayInputStream(ByteUtils.EMPTY_BYTE_ARRAY), new ByteArrayOutputStream(), 0));
112 }
113
114 @Test
115 public void testReadFullyOnChannelReadsFully() throws IOException {
116 final ByteBuffer b = ByteBuffer.allocate(20);
117 final byte[] source = new byte[20];
118 for (byte i = 0; i < 20; i++) {
119 source[i] = i;
120 }
121 readFully(source, b);
122 assertArrayEquals(source, b.array());
123 }
124
125 @Test
126 public void testReadFullyOnChannelThrowsEof() {
127 final ByteBuffer b = ByteBuffer.allocate(21);
128 final byte[] source = new byte[20];
129 for (byte i = 0; i < 20; i++) {
130 source[i] = i;
131 }
132 assertThrows(EOFException.class, () -> readFully(source, b));
133 }
134
135 @Test
136 public void testReadRangeFromChannelDoesntReadMoreThanAskedFor() throws IOException {
137 try (ReadableByteChannel in = new SeekableInMemoryByteChannel(new byte[] { 1, 2, 3, 4, 5 })) {
138 final byte[] read = IOUtils.readRange(in, 3);
139 assertArrayEquals(new byte[] { 1, 2, 3 }, read);
140 final ByteBuffer b = ByteBuffer.allocate(1);
141 assertEquals(1, in.read(b));
142 assertArrayEquals(new byte[] { 4 }, b.array());
143 }
144 }
145
146 @Test
147 public void testReadRangeFromChannelDoesntReadMoreThanAskedForWhenItGotLessInFirstReadCall() throws IOException {
148 try (ReadableByteChannel in = new SeekableInMemoryByteChannel(new byte[] { 1, 2, 3, 4, 5, 6, 7 }) {
149 @Override
150 public int read(ByteBuffer buf) throws IOException {
151
152 final ByteBuffer temp = ByteBuffer.allocate(Math.min(2, buf.remaining()));
153 final int read = super.read(temp);
154 if (read > 0) {
155 buf.put(temp.array(), 0, read);
156 }
157 return read;
158 }
159 }) {
160 final byte[] read = IOUtils.readRange(in, 5);
161 assertArrayEquals(new byte[] { 1, 2, 3, 4, 5 }, read);
162 }
163 }
164
165 @Test
166 public void testReadRangeFromChannelStopsIfThereIsNothingToReadAnymore() throws IOException {
167 try (ReadableByteChannel in = new SeekableInMemoryByteChannel(new byte[] { 1, 2, 3, 4, 5 })) {
168 final byte[] read = IOUtils.readRange(in, 10);
169 assertArrayEquals(new byte[] { 1, 2, 3, 4, 5 }, read);
170 final ByteBuffer b = ByteBuffer.allocate(1);
171 assertEquals(-1, in.read(b));
172 }
173 }
174
175 @Test
176 public void testReadRangeFromStreamDoesntReadMoreThanAskedFor() throws IOException {
177 try (ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5 })) {
178 final byte[] read = IOUtils.readRange(in, 3);
179 assertArrayEquals(new byte[] { 1, 2, 3 }, read);
180 assertEquals(4, in.read());
181 }
182 }
183
184 @Test
185 public void testReadRangeFromStreamStopsIfThereIsNothingToReadAnymore() throws IOException {
186 try (ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5 })) {
187 final byte[] read = IOUtils.readRange(in, 10);
188 assertArrayEquals(new byte[] { 1, 2, 3, 4, 5 }, read);
189 assertEquals(-1, in.read());
190 }
191 }
192
193 @Test
194 public void testReadRangeMoreThanCopyBufferSize() throws Exception {
195 final int copyBufSize = org.apache.commons.io.IOUtils.DEFAULT_BUFFER_SIZE;
196
197
198 final byte[] input = new byte[copyBufSize + 10];
199
200 try (SeekableInMemoryByteChannel in = new SeekableInMemoryByteChannel(input)) {
201
202 final int toRead = copyBufSize + 1;
203 final byte[] read = IOUtils.readRange(in, toRead);
204 assertEquals(toRead, read.length);
205 assertEquals(toRead, in.position());
206 }
207 }
208
209 @Test
210 public void testSkipUsingRead() throws Exception {
211 skip(toWrap -> new FilterInputStream(toWrap) {
212 @Override
213 public long skip(final long s) {
214 return 0;
215 }
216 });
217 }
218
219 @Test
220 public void testSkipUsingSkip() throws Exception {
221 skip(toWrap -> toWrap);
222 }
223
224 @Test
225 public void testSkipUsingSkipAndRead() throws Exception {
226 skip(toWrap -> new FilterInputStream(toWrap) {
227 boolean skipped;
228
229 @Override
230 public long skip(final long s) throws IOException {
231 if (!skipped) {
232 toWrap.skip(5);
233 skipped = true;
234 return 5;
235 }
236 return 0;
237 }
238 });
239 }
240
241 @Test
242 public void testToByteArray_InputStream() throws Exception {
243 final byte[] bytes = "ABCB".getBytes(StandardCharsets.UTF_8);
244 try (InputStream fin = new ByteArrayInputStream(bytes)) {
245 @SuppressWarnings("deprecation")
246 final byte[] out = IOUtils.toByteArray(fin);
247 assertNotNull(out);
248 assertEquals(0, fin.available());
249 assertEquals(4, out.length);
250 assertArrayEquals(bytes, out);
251 }
252 }
253
254 }