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