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.OutputStream;
26 import java.util.Arrays;
27
28 import org.junit.jupiter.api.Test;
29
30
31
32
33 class Base45OutputStreamTest extends AbstractBaseNOutputStreamTest {
34
35 private static final byte[] CR_LF = { (byte) '\r', (byte) '\n' };
36 private static final byte[] LF = { (byte) '\n' };
37
38 @Override
39 OutputStream newOutputStream() {
40 return new Base45OutputStream(new ByteArrayOutputStream());
41 }
42
43 private void testBase45EmptyOutputStream(final int chunkSize) throws Exception {
44 final byte[] emptyEncoded = {};
45 final byte[] emptyDecoded = {};
46 testByteByByte(emptyEncoded, emptyDecoded, chunkSize, CR_LF);
47 testByChunk(emptyEncoded, emptyDecoded, chunkSize, CR_LF);
48 }
49
50 @Test
51 void testBase45EmptyOutputStreamMimeChunkSize() throws Exception {
52 testBase45EmptyOutputStream(BaseNCodec.MIME_CHUNK_SIZE);
53 }
54
55 @Test
56 void testBase45EmptyOutputStreamPemChunkSize() throws Exception {
57 testBase45EmptyOutputStream(BaseNCodec.PEM_CHUNK_SIZE);
58 }
59
60 @Test
61 void testBase45OutputStreamByChunk() throws Exception {
62 byte[] decoded = StringUtils.getBytesUtf8("Hello World");
63 byte[] encoded = new Base45().encode(decoded);
64 testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CR_LF);
65 final BaseNCodec codec = new Base45();
66 for (int i = 0; i <= 150; i++) {
67 final byte[][] randomData = BaseNTestData.randomData(codec, i);
68 encoded = randomData[1];
69 decoded = randomData[0];
70 testByChunk(encoded, decoded, 0, LF);
71 }
72 }
73
74 @Test
75 void testBase45OutputStreamByteByByte() throws Exception {
76 byte[] decoded = StringUtils.getBytesUtf8("Hello World");
77 byte[] encoded = new Base45().encode(decoded);
78 testByteByByte(encoded, decoded, 76, CR_LF);
79 final BaseNCodec codec = new Base45();
80 for (int i = 0; i <= 150; i++) {
81 final byte[][] randomData = BaseNTestData.randomData(codec, i);
82 encoded = randomData[1];
83 decoded = randomData[0];
84 testByteByByte(encoded, decoded, 0, LF);
85 }
86 }
87
88 @Test
89 void testBuilder() {
90 assertNotNull(Base45OutputStream.builder().getBaseNCodec());
91 }
92
93 private void testByChunk(final byte[] encoded, final byte[] decoded, final int chunkSize, final byte[] separator) throws Exception {
94 ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
95 try (OutputStream out = Base45OutputStream.builder().setOutputStream(byteOut).setEncode(true).get()) {
96 out.write(decoded);
97 }
98 byte[] output = byteOut.toByteArray();
99 assertArrayEquals(encoded, output, "Streaming chunked Base45 encode");
100 byteOut = new ByteArrayOutputStream();
101 try (OutputStream out = Base45OutputStream.builder().setOutputStream(byteOut).setEncode(false).get()) {
102 out.write(encoded);
103 }
104 output = byteOut.toByteArray();
105 assertArrayEquals(decoded, output, "Streaming chunked Base45 decode");
106 byteOut = new ByteArrayOutputStream();
107 OutputStream out = byteOut;
108 for (int i = 0; i < 10; i++) {
109 out = Base45OutputStream.builder().setOutputStream(out).setEncode(false).get();
110 out = Base45OutputStream.builder().setOutputStream(out).setEncode(true).get();
111 }
112 out.write(decoded);
113 out.close();
114 output = byteOut.toByteArray();
115 assertArrayEquals(decoded, byteOut.toByteArray(), "Streaming chunked Base45 wrap-wrap-wrap!");
116 }
117
118 private void testByteByByte(final byte[] encoded, final byte[] decoded, final int chunkSize, final byte[] separator) throws Exception {
119 ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
120 try (OutputStream out = Base45OutputStream.builder().setOutputStream(byteOut).setEncode(true).get()) {
121 for (final byte element : decoded) {
122 out.write(element);
123 }
124 }
125 final byte[] output0 = byteOut.toByteArray();
126 assertArrayEquals(encoded, output0, "Streaming byte-by-byte Base45 encode");
127 byteOut = new ByteArrayOutputStream();
128 try (OutputStream out = Base45OutputStream.builder().setOutputStream(byteOut).setEncode(false).get()) {
129 for (final byte element : encoded) {
130 out.write(element);
131 }
132 }
133 final byte[] output1 = byteOut.toByteArray();
134 assertArrayEquals(decoded, output1,
135 () -> String.format("Streaming byte-by-byte Base45 decode, chunkSize=%d, separator=%s, encoded=%s, decoded=%s, output=%s", chunkSize,
136 Arrays.toString(separator), Arrays.toString(encoded), Arrays.toString(decoded), Arrays.toString(output1)));
137 byteOut = new ByteArrayOutputStream();
138 try (OutputStream out = Base45OutputStream.builder().setOutputStream(byteOut).setEncode(false).get()) {
139 for (final byte element : encoded) {
140 out.write(element);
141 out.flush();
142 }
143 }
144 byte[] output = byteOut.toByteArray();
145 assertArrayEquals(decoded, output, "Streaming byte-by-byte flush() Base45 decode");
146 byteOut = new ByteArrayOutputStream();
147 OutputStream out = byteOut;
148 for (int i = 0; i < 10; i++) {
149 out = Base45OutputStream.builder().setOutputStream(out).setEncode(false).get();
150 out = Base45OutputStream.builder().setOutputStream(out).setEncode(true).get();
151 }
152 for (final byte element : decoded) {
153 out.write(element);
154 }
155 out.close();
156 output = byteOut.toByteArray();
157 assertArrayEquals(decoded, output, "Streaming byte-by-byte Base45 wrap-wrap-wrap!");
158 }
159
160 @Test
161 void testWriteOutOfBounds() throws Exception {
162 final byte[] buf = new byte[1024];
163 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
164 try (Base45OutputStream out = new Base45OutputStream(bout)) {
165 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, -1, 1), "Base45OutputStream.write(buf, -1, 1)");
166 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, 1, -1), "Base45OutputStream.write(buf, 1, -1)");
167 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, buf.length + 1, 0), "Base45OutputStream.write(buf, buf.length + 1, 0)");
168 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, buf.length - 1, 2), "Base45OutputStream.write(buf, buf.length - 1, 2)");
169 }
170 }
171
172 @Test
173 void testWriteToNullCoverage() throws Exception {
174 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
175 try (Base45OutputStream out = new Base45OutputStream(bout)) {
176 assertThrows(NullPointerException.class, () -> out.write(null, 0, 0));
177 }
178 }
179 }