1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.codec.binary;
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.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29
30 import org.junit.jupiter.api.Test;
31
32
33
34
35 class Base16InputStreamTest {
36
37
38
39
40 private static final String ENCODED_B16 = "CAFEBABEFFFF";
41
42 private static final String STRING_FIXTURE = "Hello World";
43
44
45
46
47
48
49 @Test
50 void testAvailable() throws IOException {
51 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B16));
52 try (Base16InputStream b16Stream = new Base16InputStream(ins)) {
53 assertEquals(1, b16Stream.available());
54 assertEquals(6, b16Stream.skip(10));
55
56 assertEquals(0, b16Stream.available());
57 assertEquals(-1, b16Stream.read());
58 assertEquals(-1, b16Stream.read());
59 assertEquals(0, b16Stream.available());
60 }
61 }
62
63
64
65
66
67
68 @Test
69 void testBase16EmptyInputStream() throws IOException {
70 final byte[] emptyEncoded = {};
71 final byte[] emptyDecoded = {};
72 testByteByByte(emptyEncoded, emptyDecoded);
73 testByChunk(emptyEncoded, emptyDecoded);
74 }
75
76
77
78
79
80
81 @Test
82 void testBase16InputStreamByChunk() throws IOException {
83
84 byte[] encoded = StringUtils.getBytesUtf8("48656C6C6F20576F726C64");
85 byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
86 testByChunk(encoded, decoded);
87
88 encoded = StringUtils.getBytesUtf8("41");
89 decoded = new byte[] { (byte) 0x41 };
90 testByChunk(encoded, decoded);
91
92 encoded = StringUtils.getBytesUtf8(Base16TestData.ENCODED_UTF8_UPPERCASE);
93 decoded = BaseNTestData.DECODED;
94 testByChunk(encoded, decoded);
95
96 final BaseNCodec codec = Base16.builder().setLowerCase(true).get();
97 for (int i = 0; i <= 150; i++) {
98 final byte[][] randomData = BaseNTestData.randomData(codec, i);
99 encoded = randomData[1];
100 decoded = randomData[0];
101 testByChunk(encoded, decoded, true);
102 }
103 }
104
105
106
107
108
109
110 @Test
111 void testBase16InputStreamByteByByte() throws IOException {
112
113 byte[] encoded = StringUtils.getBytesUtf8("48656C6C6F20576F726C64");
114 byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
115 testByteByByte(encoded, decoded);
116
117 encoded = StringUtils.getBytesUtf8("41");
118 decoded = new byte[] { (byte) 0x41 };
119 testByteByByte(encoded, decoded);
120
121 encoded = StringUtils.getBytesUtf8(Base16TestData.ENCODED_UTF8_UPPERCASE);
122 decoded = BaseNTestData.DECODED;
123 testByteByByte(encoded, decoded);
124
125 final BaseNCodec codec = Base16.builder().setLowerCase(true).get();
126 for (int i = 0; i <= 150; i++) {
127 final byte[][] randomData = BaseNTestData.randomData(codec, i);
128 encoded = randomData[1];
129 decoded = randomData[0];
130 testByteByByte(encoded, decoded, true);
131 }
132 }
133
134 @Test
135 void testBuilder() {
136 assertNotNull(Base16InputStream.builder().getBaseNCodec());
137 }
138
139
140
141
142
143
144
145
146
147
148
149 private void testByChunk(final byte[] encoded, final byte[] decoded) throws IOException {
150 testByChunk(encoded, decoded, false);
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164 private void testByChunk(final byte[] encoded, final byte[] decoded, final boolean lowerCase) throws IOException {
165
166 try (InputStream in = new Base16InputStream(new ByteArrayInputStream(decoded), true, lowerCase)) {
167 final byte[] output = BaseNTestData.streamToBytes(in);
168 assertEquals(-1, in.read(), "EOF");
169 assertEquals(-1, in.read(), "Still EOF");
170 assertArrayEquals(encoded, output, "Streaming Base16 encode");
171 }
172
173 try (InputStream in = new Base16InputStream(new ByteArrayInputStream(encoded), false, lowerCase)) {
174 final byte[] output = BaseNTestData.streamToBytes(in);
175 assertEquals(-1, in.read(), "EOF");
176 assertEquals(-1, in.read(), "Still EOF");
177 assertArrayEquals(decoded, output, "Streaming Base16 decode");
178 }
179
180 try (InputStream in = new ByteArrayInputStream(decoded);
181 InputStream inEncode = new Base16InputStream(in, true, lowerCase);
182 InputStream inDecode = new Base16InputStream(inEncode, false, lowerCase)) {
183 final byte[] output = BaseNTestData.streamToBytes(inDecode);
184 assertEquals(-1, inDecode.read(), "EOF");
185 assertEquals(-1, inDecode.read(), "Still EOF");
186 assertArrayEquals(decoded, output, "Streaming Base16 wrap-wrap!");
187 }
188 }
189
190
191
192
193
194
195
196
197
198
199
200 private void testByteByByte(final byte[] encoded, final byte[] decoded) throws IOException {
201 testByteByByte(encoded, decoded, false);
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215 private void testByteByByte(final byte[] encoded, final byte[] decoded, final boolean lowerCase) throws IOException {
216
217 try (InputStream in = new Base16InputStream(new ByteArrayInputStream(decoded), true, lowerCase)) {
218 final byte[] output = new byte[encoded.length];
219 for (int i = 0; i < output.length; i++) {
220 output[i] = (byte) in.read();
221 }
222 assertEquals(-1, in.read(), "EOF");
223 assertEquals(-1, in.read(), "Still EOF");
224 assertArrayEquals(encoded, output, "Streaming Base16 encode");
225 }
226 try (InputStream in = Base16InputStream.builder()
227 .setInputStream(new ByteArrayInputStream(decoded))
228 .setEncode(true).setBaseNCodec(Base16.builder().setLowerCase(lowerCase).get())
229 .get()) {
230 final byte[] output = new byte[encoded.length];
231 for (int i = 0; i < output.length; i++) {
232 output[i] = (byte) in.read();
233 }
234 assertEquals(-1, in.read(), "EOF");
235 assertEquals(-1, in.read(), "Still EOF");
236 assertArrayEquals(encoded, output, "Streaming Base16 encode");
237 }
238
239 try (InputStream in = new Base16InputStream(new ByteArrayInputStream(encoded), false, lowerCase)) {
240 final byte[] output = new byte[decoded.length];
241 for (int i = 0; i < output.length; i++) {
242 output[i] = (byte) in.read();
243 }
244 assertEquals(-1, in.read(), "EOF");
245 assertEquals(-1, in.read(), "Still EOF");
246 assertArrayEquals(decoded, output, "Streaming Base16 decode");
247 }
248
249 try (InputStream in = new ByteArrayInputStream(decoded);
250 InputStream inEncode = new Base16InputStream(in, true, lowerCase);
251 InputStream inDecode = new Base16InputStream(inEncode, false, lowerCase)) {
252 final byte[] output = new byte[decoded.length];
253 for (int i = 0; i < output.length; i++) {
254 output[i] = (byte) inDecode.read();
255 }
256 assertEquals(-1, inDecode.read(), "EOF");
257 assertEquals(-1, inDecode.read(), "Still EOF");
258 assertArrayEquals(decoded, output, "Streaming Base16 wrap-wrap!");
259 }
260 }
261
262
263
264
265
266
267 @Test
268 void testMarkSupported() throws IOException {
269 final byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
270 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
271 try (Base16InputStream in = new Base16InputStream(bin, true)) {
272
273 assertFalse(in.markSupported(), "Base16InputStream.markSupported() is false");
274 }
275 }
276
277
278
279
280
281
282 @Test
283 void testRead0() throws IOException {
284 final byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
285 final byte[] buf = new byte[1024];
286 int bytesRead = 0;
287 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
288 try (Base16InputStream in = new Base16InputStream(bin, true)) {
289 bytesRead = in.read(buf, 0, 0);
290 assertEquals(0, bytesRead, "Base16InputStream.read(buf, 0, 0) returns 0");
291 }
292 }
293
294
295
296
297
298
299 @Test
300 void testReadNull() throws IOException {
301 final byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
302 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
303 try (Base16InputStream in = new Base16InputStream(bin, true)) {
304 assertThrows(NullPointerException.class, () -> in.read(null, 0, 0), "Base16InputStream.read(null, 0, 0)");
305 }
306 }
307
308
309
310
311
312
313 @Test
314 void testReadOutOfBounds() throws IOException {
315 final byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
316 final byte[] buf = new byte[1024];
317 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
318 try (Base16InputStream in = new Base16InputStream(bin, true)) {
319 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, -1, 0), "Base16InputStream.read(buf, -1, 0)");
320 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, 0, -1), "Base16InputStream.read(buf, 0, -1)");
321 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, buf.length + 1, 0), "Base16InputStream.read(buf, buf.length + 1, 0)");
322 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, buf.length - 1, 2), "Base16InputStream.read(buf, buf.length - 1, 2)");
323 }
324 }
325
326
327
328
329
330
331 @Test
332 void testSkipBig() throws IOException {
333 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B16));
334 try (Base16InputStream b16Stream = new Base16InputStream(ins)) {
335 assertEquals(6, b16Stream.skip(Integer.MAX_VALUE));
336
337 assertEquals(-1, b16Stream.read());
338 assertEquals(-1, b16Stream.read());
339 }
340 }
341
342
343
344
345
346
347 @Test
348 void testSkipNone() throws IOException {
349 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B16));
350 try (Base16InputStream b16Stream = new Base16InputStream(ins)) {
351 final byte[] actualBytes = new byte[6];
352 assertEquals(0, b16Stream.skip(0));
353 b16Stream.read(actualBytes, 0, actualBytes.length);
354 assertArrayEquals(actualBytes, new byte[] { (byte) 202, (byte) 254, (byte) 186, (byte) 190, (byte) 255, (byte) 255 });
355
356 assertEquals(-1, b16Stream.read());
357 }
358 }
359
360
361
362
363
364
365 @Test
366 void testSkipPastEnd() throws IOException {
367 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B16));
368 try (Base16InputStream b16Stream = new Base16InputStream(ins)) {
369
370 assertEquals(6, b16Stream.skip(10));
371
372 assertEquals(-1, b16Stream.read());
373 assertEquals(-1, b16Stream.read());
374 }
375 }
376
377
378
379
380
381
382 @Test
383 void testSkipToEnd() throws IOException {
384 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B16));
385 try (Base16InputStream b16Stream = new Base16InputStream(ins)) {
386
387 assertEquals(6, b16Stream.skip(6));
388
389 assertEquals(-1, b16Stream.read());
390 assertEquals(-1, b16Stream.read());
391 }
392 }
393
394
395
396
397
398
399 @Test
400 void testSkipWrongArgument() throws IOException {
401 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B16));
402 try (Base16InputStream b16Stream = new Base16InputStream(ins)) {
403 assertThrows(IllegalArgumentException.class, () -> b16Stream.skip(-10));
404 }
405
406 try (Base16InputStream b16Stream = Base16InputStream.builder().setInputStream(ins).get()) {
407 assertThrows(IllegalArgumentException.class, () -> b16Stream.skip(-10));
408 }
409 }
410 }