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.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.io.OutputStream;
27
28 import org.junit.jupiter.api.Test;
29
30
31
32
33 class Base16OutputStreamTest {
34
35 private static final String STRING_FIXTURE = "Hello World";
36
37
38
39
40
41
42 @Test
43 void testBase16EmptyOutputStream() throws IOException {
44 final byte[] emptyEncoded = {};
45 final byte[] emptyDecoded = {};
46 testByteByByte(emptyEncoded, emptyDecoded);
47 testByChunk(emptyEncoded, emptyDecoded);
48 }
49
50
51
52
53
54
55 @Test
56 void testBase16OutputStreamByChunk() throws IOException {
57
58 byte[] encoded = StringUtils.getBytesUtf8("48656C6C6F20576F726C64");
59 byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
60 testByChunk(encoded, decoded);
61
62
63 encoded = StringUtils.getBytesUtf8("41");
64 decoded = new byte[]{(byte) 0x41};
65 testByChunk(encoded, decoded);
66
67
68 final BaseNCodec codec = Base16.builder().setLowerCase(true).get();
69 for (int i = 0; i <= 150; i++) {
70 final byte[][] randomData = BaseNTestData.randomData(codec, i);
71 encoded = randomData[1];
72 decoded = randomData[0];
73 testByChunk(encoded, decoded, true);
74 }
75 }
76
77
78
79
80
81
82 @Test
83 void testBase16OutputStreamByteByByte() throws IOException {
84
85 byte[] encoded = StringUtils.getBytesUtf8("48656C6C6F20576F726C64");
86 byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE);
87 testByteByByte(encoded, decoded);
88
89 encoded = StringUtils.getBytesUtf8("41");
90 decoded = new byte[] { (byte) 0x41 };
91 testByteByByte(encoded, decoded);
92
93 final BaseNCodec codec = Base16.builder().setLowerCase(true).get();
94 for (int i = 0; i <= 150; i++) {
95 final byte[][] randomData = BaseNTestData.randomData(codec, i);
96 encoded = randomData[1];
97 decoded = randomData[0];
98 testByteByByte(encoded, decoded, true);
99 }
100 }
101
102 @Test
103 void testBuilder() {
104 assertNotNull(Base16OutputStream.builder().getBaseNCodec());
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118 private void testByChunk(final byte[] encoded, final byte[] decoded) throws IOException {
119 testByChunk(encoded, decoded, false);
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134 private void testByChunk(final byte[] encoded, final byte[] decoded, final boolean lowerCase) throws IOException {
135
136
137 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
138 OutputStream out = new Base16OutputStream(byteOut, true, lowerCase)) {
139 out.write(decoded);
140 final byte[] output = byteOut.toByteArray();
141 assertArrayEquals(encoded, output, "Streaming chunked base16 encode");
142 }
143
144
145 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
146 OutputStream out = new Base16OutputStream(byteOut, false, lowerCase)) {
147 out.write(encoded);
148 final byte[] output = byteOut.toByteArray();
149 assertArrayEquals(decoded, output, "Streaming chunked base16 decode");
150 }
151
152
153 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
154 OutputStream decoderOut = new Base16OutputStream(byteOut, false, lowerCase);
155 OutputStream encoderOut = new Base16OutputStream(decoderOut, true, lowerCase)) {
156
157 encoderOut.write(decoded);
158 final byte[] output = byteOut.toByteArray();
159
160 assertArrayEquals(decoded, output, "Streaming chunked base16 wrap-wrap!");
161 }
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175 private void testByteByByte(final byte[] encoded, final byte[] decoded) throws IOException {
176 testByteByByte(encoded, decoded, false);
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190 private void testByteByByte(final byte[] encoded, final byte[] decoded, final boolean lowerCase) throws IOException {
191
192 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
193 OutputStream out = new Base16OutputStream(byteOut, true, lowerCase)) {
194 for (final byte element : decoded) {
195 out.write(element);
196 }
197 final byte[] output = byteOut.toByteArray();
198 assertArrayEquals(encoded, output, "Streaming byte-by-byte base16 encode");
199 }
200 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
201 OutputStream out = Base16OutputStream.builder()
202 .setOutputStream(byteOut).setEncode(true).setBaseNCodec(Base16.builder().setLowerCase(lowerCase).get())
203 .get()) {
204 for (final byte element : decoded) {
205 out.write(element);
206 }
207 final byte[] output = byteOut.toByteArray();
208 assertArrayEquals(encoded, output, "Streaming byte-by-byte base16 encode");
209 }
210
211 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
212 OutputStream out = new Base16OutputStream(byteOut, false, lowerCase)) {
213 for (final byte element : encoded) {
214 out.write(element);
215 }
216 final byte[] output = byteOut.toByteArray();
217 assertArrayEquals(decoded, output, "Streaming byte-by-byte base16 decode");
218 }
219
220 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
221 OutputStream out = new Base16OutputStream(byteOut, false, lowerCase)) {
222 for (final byte element : encoded) {
223 out.write(element);
224 out.flush();
225 }
226 final byte[] output = byteOut.toByteArray();
227 assertArrayEquals(decoded, output, "Streaming byte-by-byte flush() base16 decode");
228 }
229
230 try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
231 OutputStream decoderOut = new Base16OutputStream(byteOut, false, lowerCase);
232 OutputStream encoderOut = new Base16OutputStream(decoderOut, true, lowerCase)) {
233 for (final byte element : decoded) {
234 encoderOut.write(element);
235 }
236 final byte[] output = byteOut.toByteArray();
237 assertArrayEquals(decoded, output, "Streaming byte-by-byte base16 wrap-wrap!");
238 }
239 }
240
241
242
243
244
245
246 @Test
247 void testWriteOutOfBounds() throws IOException {
248 final byte[] buf = new byte[1024];
249 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
250 try (Base16OutputStream out = new Base16OutputStream(bout)) {
251 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, -1, 1), "Base16InputStream.write(buf, -1, 0)");
252 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, 1, -1), "Base16InputStream.write(buf, 1, -1)");
253 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, buf.length + 1, 0), "Base16InputStream.write(buf, buf.length + 1, 0)");
254 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, buf.length - 1, 2), "Base16InputStream.write(buf, buf.length - 1, 2)");
255 }
256 }
257
258
259
260
261
262
263 @Test
264 void testWriteToNullCoverage() throws IOException {
265 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
266 try (Base16OutputStream out = new Base16OutputStream(bout)) {
267 assertThrows(NullPointerException.class, () -> out.write(null, 0, 0));
268 }
269 }
270 }