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