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    *      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  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  public 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      public 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      public 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     public 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     public void testInvalidConstructor2OffsetUnder() {
166         assertThrows(IllegalArgumentException.class, () -> {
167             newStream(IOUtils.EMPTY_BYTE_ARRAY, -1);
168         });
169     }
170 
171     @Test
172     public void testInvalidConstructor3LengthUnder() {
173         assertThrows(IllegalArgumentException.class, () -> {
174             newStream(IOUtils.EMPTY_BYTE_ARRAY, 0, -1);
175         });
176     }
177 
178     @Test
179     public void testInvalidConstructor3OffsetUnder() {
180         assertThrows(IllegalArgumentException.class, () -> {
181             newStream(IOUtils.EMPTY_BYTE_ARRAY, -1, 1);
182         });
183     }
184 
185     @Test
186     @SuppressWarnings("resource") // not necessary to close these resources
187     public void testInvalidReadArrayExplicitLenUnder() {
188         final byte[] buf = IOUtils.EMPTY_BYTE_ARRAY;
189         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
190         assertThrows(IndexOutOfBoundsException.class, () -> {
191             is.read(buf, 0, -1);
192         });
193     }
194 
195     @Test
196     public void testInvalidReadArrayExplicitOffsetUnder() {
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, () -> {
201             is.read(buf, -1, 1);
202         });
203     }
204 
205     @Test
206     public void testInvalidReadArrayExplicitRangeOver() {
207         final byte[] buf = IOUtils.EMPTY_BYTE_ARRAY;
208         @SuppressWarnings("resource") // not necessary to close these resources
209         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
210         assertThrows(IndexOutOfBoundsException.class, () -> {
211             is.read(buf, 0, 1);
212         });
213     }
214 
215     @Test
216     public void testInvalidReadArrayNull() {
217         final byte[] buf = null;
218         @SuppressWarnings("resource") // not necessary to close these resources
219         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
220         assertThrows(NullPointerException.class, () -> {
221             is.read(buf);
222         });
223     }
224 
225     @Test
226     public void testInvalidSkipNUnder() {
227         @SuppressWarnings("resource") // not necessary to close these resources
228         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
229         assertThrows(IllegalArgumentException.class, () -> {
230             is.skip(-1);
231         });
232     }
233 
234     @Test
235     public void testMarkReset() {
236         @SuppressWarnings("resource") // not necessary to close these resources
237         final UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
238         assertTrue(is.markSupported());
239         assertEquals(0xa, is.read());
240         assertTrue(is.markSupported());
241 
242         is.mark(10);
243 
244         assertEquals(0xb, is.read());
245         assertEquals(0xc, is.read());
246 
247         is.reset();
248 
249         assertEquals(0xb, is.read());
250         assertEquals(0xc, is.read());
251         assertEquals(END_OF_STREAM, is.read());
252 
253         is.reset();
254 
255         assertEquals(0xb, is.read());
256         assertEquals(0xc, is.read());
257         assertEquals(END_OF_STREAM, is.read());
258     }
259 
260     @Test
261     public void testReadArray() {
262         byte[] buf = new byte[10];
263         UnsynchronizedByteArrayInputStream is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
264         int read = is.read(buf);
265         assertEquals(END_OF_STREAM, read);
266         assertArrayEquals(new byte[10], buf);
267 
268         buf = IOUtils.EMPTY_BYTE_ARRAY;
269         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
270         read = is.read(buf);
271         assertEquals(0, read);
272 
273         buf = new byte[10];
274         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
275         read = is.read(buf);
276         assertEquals(3, read);
277         assertEquals(0xa, buf[0]);
278         assertEquals(0xb, buf[1]);
279         assertEquals(0xc, buf[2]);
280         assertEquals(0, buf[3]);
281 
282         buf = new byte[2];
283         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
284         read = is.read(buf);
285         assertEquals(2, read);
286         assertEquals(0xa, buf[0]);
287         assertEquals(0xb, buf[1]);
288         read = is.read(buf);
289         assertEquals(1, read);
290         assertEquals(0xc, buf[0]);
291     }
292 
293     @Test
294     public void testReadArrayExplicit() {
295         byte[] buf = new byte[10];
296         UnsynchronizedByteArrayInputStream is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
297         int read = is.read(buf, 0, 10);
298         assertEquals(END_OF_STREAM, read);
299         assertArrayEquals(new byte[10], buf);
300 
301         buf = new byte[10];
302         is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
303         read = is.read(buf, 4, 2);
304         assertEquals(END_OF_STREAM, read);
305         assertArrayEquals(new byte[10], buf);
306 
307         buf = new byte[10];
308         is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
309         read = is.read(buf, 4, 6);
310         assertEquals(END_OF_STREAM, read);
311         assertArrayEquals(new byte[10], buf);
312 
313         buf = IOUtils.EMPTY_BYTE_ARRAY;
314         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
315         read = is.read(buf, 0, 0);
316         assertEquals(0, read);
317 
318         buf = new byte[10];
319         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
320         read = is.read(buf, 0, 2);
321         assertEquals(2, read);
322         assertEquals(0xa, buf[0]);
323         assertEquals(0xb, buf[1]);
324         assertEquals(0, buf[2]);
325         read = is.read(buf, 0, 10);
326         assertEquals(1, read);
327         assertEquals(0xc, buf[0]);
328     }
329 
330     @Test
331     public void testReadSingle() {
332         UnsynchronizedByteArrayInputStream is = newStream(IOUtils.EMPTY_BYTE_ARRAY);
333         assertEquals(END_OF_STREAM, is.read());
334 
335         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
336         assertEquals(0xa, is.read());
337         assertEquals(0xb, is.read());
338         assertEquals(0xc, is.read());
339         assertEquals(END_OF_STREAM, is.read());
340     }
341 
342     @Test
343     public void testSkip() {
344         UnsynchronizedByteArrayInputStream is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
345         assertEquals(3, is.available());
346 
347         is.skip(1);
348         assertEquals(2, is.available());
349         assertEquals(0xb, is.read());
350 
351         is.skip(1);
352         assertEquals(0, is.available());
353         assertEquals(END_OF_STREAM, is.read());
354 
355         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
356         assertEquals(3, is.available());
357         is.skip(0);
358         assertEquals(3, is.available());
359         assertEquals(0xa, is.read());
360 
361         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
362         assertEquals(3, is.available());
363         is.skip(2);
364         assertEquals(1, is.available());
365         assertEquals(0xc, is.read());
366         assertEquals(END_OF_STREAM, is.read());
367 
368         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
369         assertEquals(3, is.available());
370         is.skip(3);
371         assertEquals(0, is.available());
372         assertEquals(END_OF_STREAM, is.read());
373 
374         is = newStream(new byte[] { (byte) 0xa, (byte) 0xb, (byte) 0xc });
375         assertEquals(3, is.available());
376         is.skip(999);
377         assertEquals(0, is.available());
378         assertEquals(END_OF_STREAM, is.read());
379     }
380 }