blob: 3aee5839983e5624e9685609368af6211024dad8 [file] [log] [blame]
Doug Zongkerd2affae2010-02-12 15:50:01 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Doug Zongkerab69e292010-03-29 13:23:15 -070017package android.util;
Doug Zongkerd2affae2010-02-12 15:50:01 -080018
Aurimas Liutikasbdbde552017-12-19 13:21:10 -080019import android.support.test.filters.LargeTest;
Doug Zongkerd2affae2010-02-12 15:50:01 -080020
21import java.io.ByteArrayInputStream;
22import java.io.ByteArrayOutputStream;
Aurimas Liutikasbdbde552017-12-19 13:21:10 -080023import java.io.IOException;
24import java.io.InputStream;
25import java.util.Arrays;
Doug Zongkerd2affae2010-02-12 15:50:01 -080026import java.util.Random;
Aurimas Liutikasbdbde552017-12-19 13:21:10 -080027import junit.framework.TestCase;
Doug Zongkerd2affae2010-02-12 15:50:01 -080028
Aurimas Liutikasbdbde552017-12-19 13:21:10 -080029@LargeTest
Doug Zongkerd2affae2010-02-12 15:50:01 -080030public class Base64Test extends TestCase {
31 private static final String TAG = "Base64Test";
32
33 /** Decodes a string, returning a string. */
34 private String decodeString(String in) throws Exception {
35 byte[] out = Base64.decode(in, 0);
36 return new String(out);
37 }
38
39 /**
40 * Encodes the string 'in' using 'flags'. Asserts that decoding
41 * gives the same string. Returns the encoded string.
42 */
43 private String encodeToString(String in, int flags) throws Exception {
44 String b64 = Base64.encodeToString(in.getBytes(), flags);
45 String dec = decodeString(b64);
46 assertEquals(in, dec);
47 return b64;
48 }
49
50 /** Assert that decoding 'in' throws IllegalArgumentException. */
51 private void assertBad(String in) throws Exception {
52 try {
53 byte[] out = Base64.decode(in, 0);
54 fail("should have failed to decode");
55 } catch (IllegalArgumentException e) {
56 }
57 }
58
59 /** Assert that actual equals the first len bytes of expected. */
60 private void assertEquals(byte[] expected, int len, byte[] actual) {
61 assertEquals(len, actual.length);
62 for (int i = 0; i < len; ++i) {
63 assertEquals(expected[i], actual[i]);
64 }
65 }
66
67 /** Assert that actual equals the first len bytes of expected. */
68 private void assertEquals(byte[] expected, int len, byte[] actual, int alen) {
69 assertEquals(len, alen);
70 for (int i = 0; i < len; ++i) {
71 assertEquals(expected[i], actual[i]);
72 }
73 }
74
75 /** Assert that actual equals the first len bytes of expected. */
76 private void assertEquals(byte[] expected, byte[] actual) {
77 assertEquals(expected.length, actual.length);
78 for (int i = 0; i < expected.length; ++i) {
79 assertEquals(expected[i], actual[i]);
80 }
81 }
82
83 public void testDecodeExtraChars() throws Exception {
84 // padding 0
85 assertEquals("hello, world", decodeString("aGVsbG8sIHdvcmxk"));
86 assertBad("aGVsbG8sIHdvcmxk=");
87 assertBad("aGVsbG8sIHdvcmxk==");
88 assertBad("aGVsbG8sIHdvcmxk =");
89 assertBad("aGVsbG8sIHdvcmxk = = ");
90 assertEquals("hello, world", decodeString(" aGVs bG8s IHdv cmxk "));
91 assertEquals("hello, world", decodeString(" aGV sbG8 sIHd vcmx k "));
92 assertEquals("hello, world", decodeString(" aG VsbG 8sIH dvcm xk "));
93 assertEquals("hello, world", decodeString(" a GVsb G8sI Hdvc mxk "));
94 assertEquals("hello, world", decodeString(" a G V s b G 8 s I H d v c m x k "));
95 assertEquals("hello, world", decodeString("_a*G_V*s_b*G_8*s_I*H_d*v_c*m_x*k_"));
96 assertEquals("hello, world", decodeString("aGVsbG8sIHdvcmxk"));
97
98 // padding 1
99 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPyE="));
100 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPyE"));
101 assertBad("aGVsbG8sIHdvcmxkPyE==");
102 assertBad("aGVsbG8sIHdvcmxkPyE ==");
103 assertBad("aGVsbG8sIHdvcmxkPyE = = ");
104 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E="));
105 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E"));
106 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E ="));
107 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E "));
108 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E = "));
109 assertEquals("hello, world?!", decodeString("aGVsbG8sIHdvcmxkPy E "));
110
111 // padding 2
112 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkLg=="));
113 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkLg"));
114 assertBad("aGVsbG8sIHdvcmxkLg=");
115 assertBad("aGVsbG8sIHdvcmxkLg =");
116 assertBad("aGVsbG8sIHdvcmxkLg = ");
117 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g=="));
118 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g"));
119 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g =="));
120 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g "));
121 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g = = "));
122 assertEquals("hello, world.", decodeString("aGVsbG8sIHdvcmxkL g "));
123 }
124
125 private static final byte[] BYTES = { (byte) 0xff, (byte) 0xee, (byte) 0xdd,
126 (byte) 0xcc, (byte) 0xbb, (byte) 0xaa,
127 (byte) 0x99, (byte) 0x88, (byte) 0x77 };
128
129 public void testBinaryDecode() throws Exception {
130 assertEquals(BYTES, 0, Base64.decode("", 0));
131 assertEquals(BYTES, 1, Base64.decode("/w==", 0));
132 assertEquals(BYTES, 2, Base64.decode("/+4=", 0));
133 assertEquals(BYTES, 3, Base64.decode("/+7d", 0));
134 assertEquals(BYTES, 4, Base64.decode("/+7dzA==", 0));
135 assertEquals(BYTES, 5, Base64.decode("/+7dzLs=", 0));
136 assertEquals(BYTES, 6, Base64.decode("/+7dzLuq", 0));
137 assertEquals(BYTES, 7, Base64.decode("/+7dzLuqmQ==", 0));
138 assertEquals(BYTES, 8, Base64.decode("/+7dzLuqmYg=", 0));
139 }
140
141 public void testWebSafe() throws Exception {
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800142 assertEquals(BYTES, 0, Base64.decode("", Base64.URL_SAFE));
143 assertEquals(BYTES, 1, Base64.decode("_w==", Base64.URL_SAFE));
144 assertEquals(BYTES, 2, Base64.decode("_-4=", Base64.URL_SAFE));
145 assertEquals(BYTES, 3, Base64.decode("_-7d", Base64.URL_SAFE));
146 assertEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.URL_SAFE));
147 assertEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.URL_SAFE));
148 assertEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.URL_SAFE));
149 assertEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.URL_SAFE));
150 assertEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.URL_SAFE));
Doug Zongkerd2affae2010-02-12 15:50:01 -0800151
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800152 assertEquals("", Base64.encodeToString(BYTES, 0, 0, Base64.URL_SAFE));
153 assertEquals("_w==\n", Base64.encodeToString(BYTES, 0, 1, Base64.URL_SAFE));
154 assertEquals("_-4=\n", Base64.encodeToString(BYTES, 0, 2, Base64.URL_SAFE));
155 assertEquals("_-7d\n", Base64.encodeToString(BYTES, 0, 3, Base64.URL_SAFE));
156 assertEquals("_-7dzA==\n", Base64.encodeToString(BYTES, 0, 4, Base64.URL_SAFE));
157 assertEquals("_-7dzLs=\n", Base64.encodeToString(BYTES, 0, 5, Base64.URL_SAFE));
158 assertEquals("_-7dzLuq\n", Base64.encodeToString(BYTES, 0, 6, Base64.URL_SAFE));
159 assertEquals("_-7dzLuqmQ==\n", Base64.encodeToString(BYTES, 0, 7, Base64.URL_SAFE));
160 assertEquals("_-7dzLuqmYg=\n", Base64.encodeToString(BYTES, 0, 8, Base64.URL_SAFE));
Doug Zongkerd2affae2010-02-12 15:50:01 -0800161 }
162
163 public void testFlags() throws Exception {
164 assertEquals("YQ==\n", encodeToString("a", 0));
165 assertEquals("YQ==", encodeToString("a", Base64.NO_WRAP));
166 assertEquals("YQ\n", encodeToString("a", Base64.NO_PADDING));
167 assertEquals("YQ", encodeToString("a", Base64.NO_PADDING | Base64.NO_WRAP));
168 assertEquals("YQ==\r\n", encodeToString("a", Base64.CRLF));
169 assertEquals("YQ\r\n", encodeToString("a", Base64.CRLF | Base64.NO_PADDING));
170
171 assertEquals("YWI=\n", encodeToString("ab", 0));
172 assertEquals("YWI=", encodeToString("ab", Base64.NO_WRAP));
173 assertEquals("YWI\n", encodeToString("ab", Base64.NO_PADDING));
174 assertEquals("YWI", encodeToString("ab", Base64.NO_PADDING | Base64.NO_WRAP));
175 assertEquals("YWI=\r\n", encodeToString("ab", Base64.CRLF));
176 assertEquals("YWI\r\n", encodeToString("ab", Base64.CRLF | Base64.NO_PADDING));
177
178 assertEquals("YWJj\n", encodeToString("abc", 0));
179 assertEquals("YWJj", encodeToString("abc", Base64.NO_WRAP));
180 assertEquals("YWJj\n", encodeToString("abc", Base64.NO_PADDING));
181 assertEquals("YWJj", encodeToString("abc", Base64.NO_PADDING | Base64.NO_WRAP));
182 assertEquals("YWJj\r\n", encodeToString("abc", Base64.CRLF));
183 assertEquals("YWJj\r\n", encodeToString("abc", Base64.CRLF | Base64.NO_PADDING));
184
185 assertEquals("YWJjZA==\n", encodeToString("abcd", 0));
186 assertEquals("YWJjZA==", encodeToString("abcd", Base64.NO_WRAP));
187 assertEquals("YWJjZA\n", encodeToString("abcd", Base64.NO_PADDING));
188 assertEquals("YWJjZA", encodeToString("abcd", Base64.NO_PADDING | Base64.NO_WRAP));
189 assertEquals("YWJjZA==\r\n", encodeToString("abcd", Base64.CRLF));
190 assertEquals("YWJjZA\r\n", encodeToString("abcd", Base64.CRLF | Base64.NO_PADDING));
191 }
192
193 public void testLineLength() throws Exception {
194 String in_56 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd";
195 String in_57 = in_56 + "e";
196 String in_58 = in_56 + "ef";
197 String in_59 = in_56 + "efg";
198 String in_60 = in_56 + "efgh";
199 String in_61 = in_56 + "efghi";
200
201 String prefix = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5emFi";
202 String out_56 = prefix + "Y2Q=\n";
203 String out_57 = prefix + "Y2Rl\n";
204 String out_58 = prefix + "Y2Rl\nZg==\n";
205 String out_59 = prefix + "Y2Rl\nZmc=\n";
206 String out_60 = prefix + "Y2Rl\nZmdo\n";
207 String out_61 = prefix + "Y2Rl\nZmdoaQ==\n";
208
209 // no newline for an empty input array.
210 assertEquals("", encodeToString("", 0));
211
212 assertEquals(out_56, encodeToString(in_56, 0));
213 assertEquals(out_57, encodeToString(in_57, 0));
214 assertEquals(out_58, encodeToString(in_58, 0));
215 assertEquals(out_59, encodeToString(in_59, 0));
216 assertEquals(out_60, encodeToString(in_60, 0));
217 assertEquals(out_61, encodeToString(in_61, 0));
218
219 assertEquals(out_56.replaceAll("=", ""), encodeToString(in_56, Base64.NO_PADDING));
220 assertEquals(out_57.replaceAll("=", ""), encodeToString(in_57, Base64.NO_PADDING));
221 assertEquals(out_58.replaceAll("=", ""), encodeToString(in_58, Base64.NO_PADDING));
222 assertEquals(out_59.replaceAll("=", ""), encodeToString(in_59, Base64.NO_PADDING));
223 assertEquals(out_60.replaceAll("=", ""), encodeToString(in_60, Base64.NO_PADDING));
224 assertEquals(out_61.replaceAll("=", ""), encodeToString(in_61, Base64.NO_PADDING));
225
226 assertEquals(out_56.replaceAll("\n", ""), encodeToString(in_56, Base64.NO_WRAP));
227 assertEquals(out_57.replaceAll("\n", ""), encodeToString(in_57, Base64.NO_WRAP));
228 assertEquals(out_58.replaceAll("\n", ""), encodeToString(in_58, Base64.NO_WRAP));
229 assertEquals(out_59.replaceAll("\n", ""), encodeToString(in_59, Base64.NO_WRAP));
230 assertEquals(out_60.replaceAll("\n", ""), encodeToString(in_60, Base64.NO_WRAP));
231 assertEquals(out_61.replaceAll("\n", ""), encodeToString(in_61, Base64.NO_WRAP));
232 }
233
234 /**
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800235 * Tests that Base64.Encoder.encode() does correct handling of the
Doug Zongkerd2affae2010-02-12 15:50:01 -0800236 * tail for each call.
237 *
238 * This test is disabled because while it passes if you can get it
239 * to run, android's test infrastructure currently doesn't allow
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800240 * us to get at package-private members (Base64.Encoder in
Doug Zongkerd2affae2010-02-12 15:50:01 -0800241 * this case).
242 */
243 public void XXXtestEncodeInternal() throws Exception {
244 byte[] input = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
245 byte[] output = new byte[100];
246
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800247 Base64.Encoder encoder = new Base64.Encoder(Base64.NO_PADDING | Base64.NO_WRAP,
248 output);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800249
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800250 encoder.process(input, 0, 3, false);
251 assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op);
252 assertEquals(0, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800253
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800254 encoder.process(input, 0, 3, false);
255 assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op);
256 assertEquals(0, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800257
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800258 encoder.process(input, 0, 1, false);
259 assertEquals(0, encoder.op);
260 assertEquals(1, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800261
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800262 encoder.process(input, 0, 1, false);
263 assertEquals(0, encoder.op);
264 assertEquals(2, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800265
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800266 encoder.process(input, 0, 1, false);
267 assertEquals("YWFh".getBytes(), 4, encoder.output, encoder.op);
268 assertEquals(0, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800269
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800270 encoder.process(input, 0, 2, false);
271 assertEquals(0, encoder.op);
272 assertEquals(2, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800273
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800274 encoder.process(input, 0, 2, false);
275 assertEquals("YWJh".getBytes(), 4, encoder.output, encoder.op);
276 assertEquals(1, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800277
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800278 encoder.process(input, 0, 2, false);
279 assertEquals("YmFi".getBytes(), 4, encoder.output, encoder.op);
280 assertEquals(0, encoder.tailLen);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800281
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800282 encoder.process(input, 0, 1, true);
283 assertEquals("YQ".getBytes(), 2, encoder.output, encoder.op);
Doug Zongkerd2affae2010-02-12 15:50:01 -0800284 }
285
286 private static final String lipsum =
287 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
288 "Quisque congue eleifend odio, eu ornare nulla facilisis eget. " +
289 "Integer eget elit diam, sit amet laoreet nibh. Quisque enim " +
290 "urna, pharetra vitae consequat eget, adipiscing eu ante. " +
291 "Aliquam venenatis arcu nec nibh imperdiet tempor. In id dui " +
292 "eget lorem aliquam rutrum vel vitae eros. In placerat ornare " +
293 "pretium. Curabitur non fringilla mi. Fusce ultricies, turpis " +
294 "eu ultrices suscipit, ligula nisi consectetur eros, dapibus " +
295 "aliquet dui sapien a turpis. Donec ultricies varius ligula, " +
296 "ut hendrerit arcu malesuada at. Praesent sed elit pretium " +
297 "eros luctus gravida. In ac dolor lorem. Cras condimentum " +
298 "convallis elementum. Phasellus vel felis in nulla ultrices " +
299 "venenatis. Nam non tortor non orci convallis convallis. " +
300 "Nam tristique lacinia hendrerit. Pellentesque habitant morbi " +
301 "tristique senectus et netus et malesuada fames ac turpis " +
302 "egestas. Vivamus cursus, nibh eu imperdiet porta, magna " +
303 "ipsum mollis mauris, sit amet fringilla mi nisl eu mi. " +
304 "Phasellus posuere, leo at ultricies vehicula, massa risus " +
305 "volutpat sapien, eu tincidunt diam ipsum eget nulla. Cras " +
306 "molestie dapibus commodo. Ut vel tellus at massa gravida " +
307 "semper non sed orci.";
308
309 public void testInputStream() throws Exception {
310 int[] flagses = { Base64.DEFAULT,
311 Base64.NO_PADDING,
312 Base64.NO_WRAP,
313 Base64.NO_PADDING | Base64.NO_WRAP,
314 Base64.CRLF,
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800315 Base64.URL_SAFE };
Doug Zongkerd2affae2010-02-12 15:50:01 -0800316 int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
317 Random rng = new Random(32176L);
318
319 // Test input needs to be at least 2048 bytes to fill up the
320 // read buffer of Base64InputStream.
321 byte[] plain = (lipsum + lipsum + lipsum + lipsum + lipsum).getBytes();
322
323 for (int flags: flagses) {
324 byte[] encoded = Base64.encode(plain, flags);
325
326 ByteArrayInputStream bais;
327 Base64InputStream b64is;
328 byte[] actual = new byte[plain.length * 2];
329 int ap;
330 int b;
331
332 // ----- test decoding ("encoded" -> "plain") -----
333
334 // read as much as it will give us in one chunk
335 bais = new ByteArrayInputStream(encoded);
336 b64is = new Base64InputStream(bais, flags);
337 ap = 0;
338 while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) {
339 ap += b;
340 }
341 assertEquals(actual, ap, plain);
342
343 // read individual bytes
344 bais = new ByteArrayInputStream(encoded);
345 b64is = new Base64InputStream(bais, flags);
346 ap = 0;
347 while ((b = b64is.read()) != -1) {
348 actual[ap++] = (byte) b;
349 }
350 assertEquals(actual, ap, plain);
351
352 // mix reads of variously-sized arrays with one-byte reads
353 bais = new ByteArrayInputStream(encoded);
354 b64is = new Base64InputStream(bais, flags);
355 ap = 0;
356 readloop: while (true) {
357 int l = writeLengths[rng.nextInt(writeLengths.length)];
358 if (l >= 0) {
359 b = b64is.read(actual, ap, l);
360 if (b == -1) break readloop;
361 ap += b;
362 } else {
363 for (int i = 0; i < -l; ++i) {
364 if ((b = b64is.read()) == -1) break readloop;
365 actual[ap++] = (byte) b;
366 }
367 }
368 }
369 assertEquals(actual, ap, plain);
370
371 // ----- test encoding ("plain" -> "encoded") -----
372
373 // read as much as it will give us in one chunk
374 bais = new ByteArrayInputStream(plain);
375 b64is = new Base64InputStream(bais, flags, true);
376 ap = 0;
377 while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) {
378 ap += b;
379 }
380 assertEquals(actual, ap, encoded);
381
382 // read individual bytes
383 bais = new ByteArrayInputStream(plain);
384 b64is = new Base64InputStream(bais, flags, true);
385 ap = 0;
386 while ((b = b64is.read()) != -1) {
387 actual[ap++] = (byte) b;
388 }
389 assertEquals(actual, ap, encoded);
390
391 // mix reads of variously-sized arrays with one-byte reads
392 bais = new ByteArrayInputStream(plain);
393 b64is = new Base64InputStream(bais, flags, true);
394 ap = 0;
395 readloop: while (true) {
396 int l = writeLengths[rng.nextInt(writeLengths.length)];
397 if (l >= 0) {
398 b = b64is.read(actual, ap, l);
399 if (b == -1) break readloop;
400 ap += b;
401 } else {
402 for (int i = 0; i < -l; ++i) {
403 if ((b = b64is.read()) == -1) break readloop;
404 actual[ap++] = (byte) b;
405 }
406 }
407 }
408 assertEquals(actual, ap, encoded);
409 }
410 }
411
Jesse Wilson64b25cf2010-09-22 10:28:27 -0700412 /** http://b/3026478 */
413 public void testSingleByteReads() throws IOException {
414 InputStream in = new Base64InputStream(
415 new ByteArrayInputStream("/v8=".getBytes()), Base64.DEFAULT);
416 assertEquals(254, in.read());
417 assertEquals(255, in.read());
418 }
419
Doug Zongkerd2affae2010-02-12 15:50:01 -0800420 /**
421 * Tests that Base64OutputStream produces exactly the same results
422 * as calling Base64.encode/.decode on an in-memory array.
423 */
424 public void testOutputStream() throws Exception {
425 int[] flagses = { Base64.DEFAULT,
426 Base64.NO_PADDING,
427 Base64.NO_WRAP,
428 Base64.NO_PADDING | Base64.NO_WRAP,
429 Base64.CRLF,
Doug Zongker9df2ffd2010-02-14 13:48:49 -0800430 Base64.URL_SAFE };
Doug Zongkerd2affae2010-02-12 15:50:01 -0800431 int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
432 Random rng = new Random(32176L);
433
434 // Test input needs to be at least 1024 bytes to test filling
435 // up the write(int) buffer of Base64OutputStream.
436 byte[] plain = (lipsum + lipsum).getBytes();
437
438 for (int flags: flagses) {
439 byte[] encoded = Base64.encode(plain, flags);
440
441 ByteArrayOutputStream baos;
442 Base64OutputStream b64os;
443 byte[] actual;
444 int p;
445
446 // ----- test encoding ("plain" -> "encoded") -----
447
448 // one large write(byte[]) of the whole input
449 baos = new ByteArrayOutputStream();
450 b64os = new Base64OutputStream(baos, flags);
451 b64os.write(plain);
452 b64os.close();
453 actual = baos.toByteArray();
454 assertEquals(encoded, actual);
455
456 // many calls to write(int)
457 baos = new ByteArrayOutputStream();
458 b64os = new Base64OutputStream(baos, flags);
459 for (int i = 0; i < plain.length; ++i) {
460 b64os.write(plain[i]);
461 }
462 b64os.close();
463 actual = baos.toByteArray();
464 assertEquals(encoded, actual);
465
466 // intermixed sequences of write(int) with
467 // write(byte[],int,int) of various lengths.
468 baos = new ByteArrayOutputStream();
469 b64os = new Base64OutputStream(baos, flags);
470 p = 0;
471 while (p < plain.length) {
472 int l = writeLengths[rng.nextInt(writeLengths.length)];
473 l = Math.min(l, plain.length-p);
474 if (l >= 0) {
475 b64os.write(plain, p, l);
476 p += l;
477 } else {
478 l = Math.min(-l, plain.length-p);
479 for (int i = 0; i < l; ++i) {
480 b64os.write(plain[p+i]);
481 }
482 p += l;
483 }
484 }
485 b64os.close();
486 actual = baos.toByteArray();
487 assertEquals(encoded, actual);
488
489 // ----- test decoding ("encoded" -> "plain") -----
490
491 // one large write(byte[]) of the whole input
492 baos = new ByteArrayOutputStream();
493 b64os = new Base64OutputStream(baos, flags, false);
494 b64os.write(encoded);
495 b64os.close();
496 actual = baos.toByteArray();
497 assertEquals(plain, actual);
498
499 // many calls to write(int)
500 baos = new ByteArrayOutputStream();
501 b64os = new Base64OutputStream(baos, flags, false);
502 for (int i = 0; i < encoded.length; ++i) {
503 b64os.write(encoded[i]);
504 }
505 b64os.close();
506 actual = baos.toByteArray();
507 assertEquals(plain, actual);
508
509 // intermixed sequences of write(int) with
510 // write(byte[],int,int) of various lengths.
511 baos = new ByteArrayOutputStream();
512 b64os = new Base64OutputStream(baos, flags, false);
513 p = 0;
514 while (p < encoded.length) {
515 int l = writeLengths[rng.nextInt(writeLengths.length)];
516 l = Math.min(l, encoded.length-p);
517 if (l >= 0) {
518 b64os.write(encoded, p, l);
519 p += l;
520 } else {
521 l = Math.min(-l, encoded.length-p);
522 for (int i = 0; i < l; ++i) {
523 b64os.write(encoded[p+i]);
524 }
525 p += l;
526 }
527 }
528 b64os.close();
529 actual = baos.toByteArray();
530 assertEquals(plain, actual);
531 }
532 }
533}