View Javadoc
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    *      https://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  package org.apache.commons.io.input;
18  
19  import static org.apache.commons.io.input.UnsynchronizedByteArrayInputStream.END_OF_STREAM;
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.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  import static org.junit.jupiter.api.Assertions.fail;
25  
26  import java.io.IOException;
27  
28  import org.apache.commons.io.IOUtils;
29  import org.junit.jupiter.api.Test;
30  
31  /**
32   * Basic unit tests for the alternative ByteArrayInputStream implementation.
33   */
34  class UnsynchronizedByteArrayInputStreamTest {
35  
36      private UnsynchronizedByteArrayInputStream newStream(final byte[] buffer) {
37          try {
38              return UnsynchronizedByteArrayInputStream.builder().setByteArray(buffer).get();
39          } catch (final IOException e) {
40              fail("Should never happen because no conversion is needed.", e);
41              return null;
42          }
43      }
44  
45      private UnsynchronizedByteArrayInputStream newStream(final byte[] buffer, final int offset) {
46          try {
47              return UnsynchronizedByteArrayInputStream.builder().setByteArray(buffer).setOffset(offset).get();
48          } catch (final IOException e) {
49              fail("Should never happen because no conversion is needed.", e);
50              return null;
51          }
52      }
53  
54      private UnsynchronizedByteArrayInputStream newStream(final byte[] buffer, final int offset, final int length) {
55          try {
56              return UnsynchronizedByteArrayInputStream.builder().setByteArray(buffer).setOffset(offset).setLength(length).get();
57          } catch (final IOException e) {
58              fail("Should never happen because no conversion is needed.", e);
59              return null;
60          }
61      }
62  
63      @Test
64      void testConstructor1() throws IOException {
65          final byte[] empty = IOUtils.EMPTY_BYTE_ARRAY;
66          final byte[] one = new byte[1];
67          final byte[] some = new byte[25];
68  
69          try (UnsynchronizedByteArrayInputStream is = newStream(empty)) {
70              assertEquals(empty.length, is.available());
71          }
72          try (UnsynchronizedByteArrayInputStream is = newStream(one)) {
73              assertEquals(one.length, is.available());
74          }
75          try (UnsynchronizedByteArrayInputStream is = newStream(some)) {
76              assertEquals(some.length, is.available());
77          }
78      }
79  
80      @Test
81      @SuppressWarnings("resource") // not necessary to close these resources
82      void testConstructor2() {
83          final byte[] empty = IOUtils.EMPTY_BYTE_ARRAY;
84          final byte[] one = new byte[1];
85          final byte[] some = new byte[25];
86  
87          UnsynchronizedByteArrayInputStream is = newStream(empty, 0);
88          assertEquals(empty.length, is.available());
89          is = newStream(empty, 1);
90          assertEquals(0, is.available());
91  
92          is = newStream(one, 0);
93          assertEquals(one.length, is.available());
94          is = newStream(one, 1);
95          assertEquals(0, is.available());
96          is = newStream(one, 2);
97          assertEquals(0, is.available());
98  
99          is = newStream(some, 0);
100         assertEquals(some.length, is.available());
101         is = newStream(some, 1);
102         assertEquals(some.length - 1, is.available());
103         is = newStream(some, 10);
104         assertEquals(some.length - 10, is.available());
105         is = newStream(some, some.length);
106         assertEquals(0, is.available());
107     }
108 
109     @Test
110     @SuppressWarnings("resource") // not necessary to close these resources
111     void testConstructor3() {
112         final byte[] empty = IOUtils.EMPTY_BYTE_ARRAY;
113         final byte[] one = new byte[1];
114         final byte[] some = new byte[25];
115 
116         UnsynchronizedByteArrayInputStream is = newStream(empty, 0);
117         assertEquals(empty.length, is.available());
118         is = newStream(empty, 1);
119         assertEquals(0, is.available());
120         is = newStream(empty, 0, 1);
121         assertEquals(0, is.available());
122         is = newStream(empty, 1, 1);
123         assertEquals(0, is.available());
124 
125         is = newStream(one, 0);
126         assertEquals(one.length, is.available());
127         is = newStream(one, 1);
128         assertEquals(one.length - 1, is.available());
129         is = newStream(one, 2);
130         assertEquals(0, is.available());
131         is = newStream(one, 0, 1);
132         assertEquals(1, is.available());
133         is = newStream(one, 1, 1);
134         assertEquals(0, is.available());
135         is = newStream(one, 0, 2);
136         assertEquals(1, is.available());
137         is = newStream(one, 2, 1);
138         assertEquals(0, is.available());
139         is = newStream(one, 2, 2);
140         assertEquals(0, is.available());
141 
142         is = newStream(some, 0);
143         assertEquals(some.length, is.available());
144         is = newStream(some, 1);
145         assertEquals(some.length - 1, is.available());
146         is = newStream(some, 10);
147         assertEquals(some.length - 10, is.available());
148         is = newStream(some, some.length);
149         assertEquals(0, is.available());
150         is = newStream(some, some.length, some.length);
151         assertEquals(0, is.available());
152         is = newStream(some, some.length - 1, some.length);
153         assertEquals(1, is.available());
154         is = newStream(some, 0, 7);
155         assertEquals(7, is.available());
156         is = newStream(some, 7, 7);
157         assertEquals(7, is.available());
158         is = newStream(some, 0, some.length * 2);
159         assertEquals(some.length, is.available());
160         is = newStream(some, some.length - 1, 7);
161         assertEquals(1, is.available());
162     }
163 
164     @Test
165     void testInvalidConstructor2OffsetUnder() {
166         assertThrows(IllegalArgumentException.class, () -> newStream(IOUtils.EMPTY_BYTE_ARRAY, -1));
167     }
168 
169     @Test
170     void testInvalidConstructor3LengthUnder() {
171         assertThrows(IllegalArgumentException.class, () -> newStream(IOUtils.EMPTY_BYTE_ARRAY, 0, -1));
172     }
173 
174     @Test
175     void testInvalidConstructor3OffsetUnder() {
176         assertThrows(IllegalArgumentException.class, () -> newStream(IOUtils.EMPTY_BYTE_ARRAY, -1, 1));
177     }
178 
179     @Test
180     @SuppressWarnings("resource") // not necessary to close these resources
181     void testInvalidReadArrayExplicitLenUnder() {
182         final byte[] buf = IOUtils.EMPTY_BYTE_ARRAY;
183         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
184         assertThrows(IndexOutOfBoundsException.class, () -> is.read(buf, 0, -1));
185     }
186 
187     @Test
188     void testInvalidReadArrayExplicitOffsetUnder() {
189         final byte[] buf = IOUtils.EMPTY_BYTE_ARRAY;
190         @SuppressWarnings("resource") // not necessary to close these resources
191         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
192         assertThrows(IndexOutOfBoundsException.class, () -> is.read(buf, -1, 1));
193     }
194 
195     @Test
196     void testInvalidReadArrayExplicitRangeOver() {
197         final byte[] buf = IOUtils.EMPTY_BYTE_ARRAY;
198         @SuppressWarnings("resource") // not necessary to close these resources
199         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
200         assertThrows(IndexOutOfBoundsException.class, () -> is.read(buf, 0, 1));
201     }
202 
203     @Test
204     void testInvalidReadArrayNull() {
205         final byte[] buf = null;
206         @SuppressWarnings("resource") // not necessary to close these resources
207         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
208         assertThrows(NullPointerException.class, () -> is.read(buf));
209     }
210 
211     @Test
212     void testInvalidSkipNUnder() {
213         @SuppressWarnings("resource") // not necessary to close these resources
214         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
215         assertThrows(IllegalArgumentException.class, () -> is.skip(-1));
216     }
217 
218     @Test
219     void testMarkReset() {
220         @SuppressWarnings("resource") // not necessary to close these resources
221         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
222         assertTrue(is.markSupported());
223         assertEquals(0xa, is.read());
224         assertTrue(is.markSupported());
225 
226         is.mark(10);
227 
228         assertEquals(0xb, is.read());
229         assertEquals(0xc, is.read());
230 
231         is.reset();
232 
233         assertEquals(0xb, is.read());
234         assertEquals(0xc, is.read());
235         assertEquals(END_OF_STREAM, is.read());
236 
237         is.reset();
238 
239         assertEquals(0xb, is.read());
240         assertEquals(0xc, is.read());
241         assertEquals(END_OF_STREAM, is.read());
242     }
243 
244     @Test
245     void testReadArray() {
246         byte[] buf = new byte[10];
247         UnsynchronizedByteArrayInputStream is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
248         int read = is.read(buf);
249         assertEquals(END_OF_STREAM, read);
250         assertArrayEquals(new byte[10], buf);
251 
252         buf = IOUtils.EMPTY_BYTE_ARRAY;
253         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
254         read = is.read(buf);
255         assertEquals(0, read);
256 
257         buf = new byte[10];
258         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
259         read = is.read(buf);
260         assertEquals(3, read);
261         assertEquals(0xa, buf[0]);
262         assertEquals(0xb, buf[1]);
263         assertEquals(0xc, buf[2]);
264         assertEquals(0, buf[3]);
265 
266         buf = new byte[2];
267         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
268         read = is.read(buf);
269         assertEquals(2, read);
270         assertEquals(0xa, buf[0]);
271         assertEquals(0xb, buf[1]);
272         read = is.read(buf);
273         assertEquals(1, read);
274         assertEquals(0xc, buf[0]);
275     }
276 
277     @Test
278     void testReadArrayExplicit() {
279         byte[] buf = new byte[10];
280         UnsynchronizedByteArrayInputStream is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
281         int read = is.read(buf, 0, 10);
282         assertEquals(END_OF_STREAM, read);
283         assertArrayEquals(new byte[10], buf);
284 
285         buf = new byte[10];
286         is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
287         read = is.read(buf, 4, 2);
288         assertEquals(END_OF_STREAM, read);
289         assertArrayEquals(new byte[10], buf);
290 
291         buf = new byte[10];
292         is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
293         read = is.read(buf, 4, 6);
294         assertEquals(END_OF_STREAM, read);
295         assertArrayEquals(new byte[10], buf);
296 
297         buf = IOUtils.EMPTY_BYTE_ARRAY;
298         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
299         read = is.read(buf, 0, 0);
300         assertEquals(0, read);
301 
302         buf = new byte[10];
303         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
304         read = is.read(buf, 0, 2);
305         assertEquals(2, read);
306         assertEquals(0xa, buf[0]);
307         assertEquals(0xb, buf[1]);
308         assertEquals(0, buf[2]);
309         read = is.read(buf, 0, 10);
310         assertEquals(1, read);
311         assertEquals(0xc, buf[0]);
312     }
313 
314     @Test
315     void testReadSingle() {
316         UnsynchronizedByteArrayInputStream is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
317         assertEquals(END_OF_STREAM, is.read());
318 
319         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
320         assertEquals(0xa, is.read());
321         assertEquals(0xb, is.read());
322         assertEquals(0xc, is.read());
323         assertEquals(END_OF_STREAM, is.read());
324     }
325 
326     @Test
327     void testSkip() {
328         UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
329         assertEquals(3, is.available());
330 
331         is.skip(1);
332         assertEquals(2, is.available());
333         assertEquals(0xb, is.read());
334 
335         is.skip(1);
336         assertEquals(0, is.available());
337         assertEquals(END_OF_STREAM, is.read());
338 
339         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
340         assertEquals(3, is.available());
341         is.skip(0);
342         assertEquals(3, is.available());
343         assertEquals(0xa, is.read());
344 
345         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
346         assertEquals(3, is.available());
347         is.skip(2);
348         assertEquals(1, is.available());
349         assertEquals(0xc, is.read());
350         assertEquals(END_OF_STREAM, is.read());
351 
352         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
353         assertEquals(3, is.available());
354         is.skip(3);
355         assertEquals(0, is.available());
356         assertEquals(END_OF_STREAM, is.read());
357 
358         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
359         assertEquals(3, is.available());
360         is.skip(999);
361         assertEquals(0, is.available());
362         assertEquals(END_OF_STREAM, is.read());
363     }
364 }