1 4 package com.tc.io; 5 6 import com.tc.bytes.TCByteBuffer; 7 import com.tc.bytes.TCByteBufferFactory; 8 import com.tc.io.TCByteBufferOutputStream.Mark; 9 import com.tc.test.TCTestCase; 10 11 import java.io.ByteArrayOutputStream ; 12 import java.io.IOException ; 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.List ; 16 import java.util.Random ; 17 18 public class TCByteBufferOutputStreamTest extends TCTestCase { 19 20 final Random random = new Random (); 21 22 public void testMultipleToArray() { 23 for (int i = 0; i < 250; i++) { 24 25 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(random.nextInt(100) + 1, false); 26 int bytesToWrite = random.nextInt(75) + 50; 27 28 for (int n = 0; n < bytesToWrite; n++) { 29 bbos.write(42); 30 } 31 32 assertEquals(bytesToWrite, bbos.getBytesWritten()); 33 TCByteBuffer[] data = bbos.toArray(); 34 assertEquals(bytesToWrite, length(data)); 35 36 for (int j = 0; j < 10; j++) { 37 bbos.toArray(); 38 } 39 } 40 } 41 42 public void testMark() { 43 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 44 TCByteBufferOutputStream output = new TCByteBufferOutputStream(32, false); 45 for (int i = 0; i < 30; i++) { 46 output.write(1); 47 baos.write(1); 48 } 49 50 Mark mark1 = output.mark(); 51 for (int i = 0; i < 4; i++) { 52 output.write(0); 53 baos.write(i + 1); 54 } 55 56 for (int i = 0; i < 30; i++) { 57 output.write(1); 58 baos.write(1); 59 } 60 61 Mark mark2 = output.mark(); 62 output.write(0); 63 int b = random.nextInt(); 64 baos.write(b); 65 66 int written = output.getBytesWritten(); 67 mark1.write(new byte[] { 1, 2, 3, 4 }); assertEquals(written, output.getBytesWritten()); 69 mark2.write(b); assertEquals(written, output.getBytesWritten()); 71 72 compareData(baos.toByteArray(), output.toArray()); 73 74 try { 76 mark1.write(1); 77 fail(); 78 } catch (IllegalStateException ise) { 79 } 81 82 try { 83 mark1.write(new byte[2]); 84 fail(); 85 } catch (IllegalStateException ise) { 86 } 88 89 try { 90 output.mark(); 91 fail(); 92 } catch (IllegalStateException ise) { 93 } 95 96 } 97 98 public void testInvalidWriteThroughMark() { 99 TCByteBufferOutputStream output = new TCByteBufferOutputStream(); 100 output.write(new byte[30]); 101 Mark mark1 = output.mark(); 102 103 try { 104 mark1.write(0); 105 fail(); 106 } catch (IllegalArgumentException iae) { 107 } 109 110 try { 111 mark1.write(new byte[1]); 112 fail(); 113 } catch (IllegalArgumentException iae) { 114 } 116 117 output.write(1); 118 int written = output.getBytesWritten(); 119 mark1.write(1); 120 assertEquals(written, output.getBytesWritten()); 121 mark1.write(new byte[0]); 122 assertEquals(written, output.getBytesWritten()); 123 mark1.write(new byte[1]); 124 assertEquals(written, output.getBytesWritten()); 125 126 try { 127 mark1.write(new byte[2]); 128 fail(); 129 } catch (IllegalArgumentException iae) { 130 } 132 133 } 134 135 public void testRandomMark() throws IOException { 136 for (int i = 0; i < 500; i++) { 137 doRandomMark(); 138 } 139 } 140 141 private void doRandomMark() throws IOException { 142 int initial = random.nextInt(10) + 1; 143 int max = initial + random.nextInt(1024) + 1; 144 TCByteBufferOutputStream output = new TCByteBufferOutputStream(initial, max, false); 145 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 146 List data = new ArrayList (); 147 List marks = new ArrayList (); 148 149 for (int i = 0; i < 1000; i++) { 150 marks.add(output.mark()); 151 152 if (random.nextBoolean()) { 153 byte[] b = new byte[random.nextInt(10)]; 154 random.nextBytes(b); 155 baos.write(b); 156 output.write(new byte[b.length]); 157 data.add(b); 158 } else { 159 int b = random.nextInt(); 160 output.write(0); 161 baos.write(b); 162 data.add(new byte[] { (byte) b }); 163 } 164 165 if (random.nextInt(10) > 6) { 166 byte[] b = new byte[random.nextInt(5) + 1]; 167 random.nextBytes(b); 168 baos.write(b); 169 output.write(b); 170 } 171 } 172 173 for (int i = 0, n = marks.size(); i < n; i++) { 174 Mark mark = (Mark) marks.get(i); 175 byte[] b = (byte[]) data.get(i); 176 if (b.length == 1) { 177 mark.write(b[0]); 178 } else { 179 mark.write(b); 180 } 181 } 182 183 compareData(baos.toByteArray(), output.toArray()); 184 } 185 186 public void testArrayWriteZeroLength() { 187 TCByteBufferOutputStream output = new TCByteBufferOutputStream(); 188 189 TCByteBuffer[] bufs = new TCByteBuffer[5]; 190 TCByteBuffer bufZeroLen = TCByteBufferFactory.getInstance(false, 0); 191 bufs[0] = bufZeroLen; 192 bufs[1] = TCByteBufferFactory.getInstance(false, 10); 193 bufs[2] = bufZeroLen; 194 bufs[3] = bufZeroLen; 195 bufs[4] = bufZeroLen; 196 long buflength = length(bufs); 197 198 output.write(bufs); 199 assertEquals(buflength, output.getBytesWritten()); 200 201 TCByteBuffer[] bufsOut = output.toArray(); 202 assertTrue(bufsOut.length < bufs.length); } 204 205 public void testBytesWritten() { 206 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(); 207 assertEquals(0, bbos.getBytesWritten()); 208 209 bbos.write(42); 210 assertEquals(1, bbos.getBytesWritten()); 211 212 bbos.write(new byte[10]); 213 assertEquals(11, bbos.getBytesWritten()); 214 215 bbos.write(new byte[10], 1, 2); 216 assertEquals(13, bbos.getBytesWritten()); 217 218 try { 220 bbos.write(new byte[10], 10, 1); 221 fail(); 222 } catch (IndexOutOfBoundsException ioobe) { 223 } 225 assertEquals(13, bbos.getBytesWritten()); 226 227 bbos.write(new byte[0]); 228 assertEquals(13, bbos.getBytesWritten()); 229 } 230 231 public void testBasic() { 232 int blockSize = 4096; 233 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(blockSize, false); 234 int num = 10; 235 236 byte write = 0; 237 for (int i = 0; i < blockSize * num; i++) { 238 bbos.write(write++); 239 } 240 241 TCByteBuffer[] data = bbos.toArray(); 242 assertEquals(data.length, num); 243 244 for (int i = 0; i < data.length; i++) { 245 assertNotNull(data[i]); 246 assertEquals(0, data[i].position()); 247 assertEquals(blockSize, data[i].limit()); 248 } 249 250 byte expect = 0; 251 for (int i = 0; i < data.length; i++) { 252 TCByteBuffer buf = data[i]; 253 while (buf.hasRemaining()) { 254 byte read = buf.get(); 255 assertEquals(expect++, read); 256 } 257 } 258 259 } 260 261 public void testRandom() throws IOException { 262 for (int i = 0; i < 100; i++) { 263 doRandom(); 264 } 265 } 266 267 public void testBasicConsolidation() { 268 TCByteBufferOutputStream os = new TCByteBufferOutputStream(32, 4096, false); 269 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 270 271 for (int i = 0; i < 8192; i++) { 272 byte b = (byte) random.nextInt(); 273 baos.write(b); 274 os.write(b); 275 } 276 277 TCByteBuffer[] bufs = os.toArray(); 278 assertEquals(2, bufs.length); 279 assertEquals(4096, bufs[0].limit()); 280 assertEquals(4096, bufs[1].limit()); 281 282 compareData(baos.toByteArray(), bufs); 283 } 284 285 public void doRandom() throws IOException { 286 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 288 289 final int bufSize = random.nextInt(50) + 1; 290 291 TCByteBufferOutputStream os = new TCByteBufferOutputStream(bufSize, false); 292 293 for (int i = 0; i < bufSize * 3; i++) { 294 int streamLen = os.getBytesWritten(); 295 int whichWrite = random.nextInt(4); 296 switch (whichWrite) { 297 case 0: { byte b = (byte) random.nextInt(); 299 baos.write(b); 300 os.write(b); 301 assertEquals(streamLen + 1, os.getBytesWritten()); 302 break; 303 } 304 case 1: { byte b[] = new byte[random.nextInt(bufSize * 2)]; 306 random.nextBytes(b); 307 baos.write(b); 308 os.write(b); 309 break; 310 } 311 case 2: { byte b[] = new byte[random.nextInt(bufSize * 2)]; 313 random.nextBytes(b); 314 int off = b.length == 0 ? 0 : random.nextInt(b.length); 315 int len = b.length == 0 ? 0 : random.nextInt(b.length - off); 316 baos.write(b, off, len); 317 os.write(b, off, len); 318 assertEquals(streamLen + len, os.getBytesWritten()); 319 break; 320 } 321 case 3: { int num = random.nextInt(5); 323 TCByteBuffer[] b = new TCByteBuffer[num]; 324 for (int n = 0; n < b.length; n++) { 325 TCByteBuffer buf = TCByteBufferFactory.getInstance(false, random.nextInt(bufSize * 2)); 326 byte[] bites = new byte[buf.limit()]; 327 random.nextBytes(bites); 328 buf.put(bites); 329 buf.position(0); 330 b[n] = buf; 331 baos.write(bites); 332 } 333 os.write(b); 334 assertEquals(streamLen + length(b), os.getBytesWritten()); 335 break; 336 } 337 default: { 338 fail("unknown write: " + whichWrite); 339 } 340 } 341 } 342 343 TCByteBuffer[] bufsOut = os.toArray(); 344 assertNoZeroLength(bufsOut); 345 346 compareData(baos.toByteArray(), os.toArray()); 347 } 348 349 private void assertNoZeroLength(TCByteBuffer[] bufs) { 350 for (int i = 0; i < bufs.length; i++) { 351 assertTrue("Buffer " + i + " has zero length", bufs[i].limit() > 0); 352 } 353 } 354 355 private void compareData(byte[] compare, TCByteBuffer[] test) { 356 if (test.length == 0) { 357 assertEquals(0, compare.length); 358 return; 359 } 360 361 int index = 0; 362 for (int i = 0; i < compare.length; i++) { 363 byte b = compare[i]; 364 while (!test[index].hasRemaining()) { 365 index++; 366 } 367 byte b2 = test[index].get(); 368 assertEquals(b, b2); 369 } 370 371 assertFalse(test[index].hasRemaining()); 372 } 373 374 private int length(TCByteBuffer[] b) { 375 int rv = 0; 376 for (int i = 0; i < b.length; i++) { 377 rv += b[i].limit(); 378 } 379 return rv; 380 } 381 382 public void testWithArrayWrite() { 383 int blockSize = 4096; 384 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(blockSize, false); 385 int num = 10; 386 387 byte write = 0; 388 for (int i = 0; i < blockSize * num; i++) { 389 bbos.write(write++); 390 } 391 392 TCByteBuffer[] b = new TCByteBuffer[1]; 393 byte[] s = "Hello Steve".getBytes(); 394 b[0] = TCByteBufferFactory.getInstance(false, s.length); 395 b[0].put(s); 396 b[0].flip(); 397 bbos.write(b); 398 399 TCByteBuffer[] data = bbos.toArray(); 400 assertEquals(num + 1, data.length); 401 402 for (int i = 0; i < data.length - 1; i++) { 403 assertNotNull(data[i]); 404 assertEquals(0, data[i].position()); 405 assertEquals(blockSize, data[i].limit()); 406 } 407 408 int last = data.length - 1; 409 assertNotNull(data[last]); 410 assertEquals(0, data[last].position()); 411 412 byte expect = 0; 413 for (int i = 0; i < data.length - 1; i++) { 414 TCByteBuffer buf = data[i]; 415 while (buf.hasRemaining()) { 416 byte read = buf.get(); 417 assertEquals(expect++, read); 418 } 419 } 420 byte[] s2 = new byte[s.length]; 421 data[last].get(s2); 422 assertTrue(Arrays.equals(s, s2)); 423 assertFalse(data[last].hasRemaining()); 424 } 425 426 public void testExceptions() { 427 try { 428 new TCByteBufferOutputStream(0, false); 429 fail(); 430 } catch (IllegalArgumentException iae) { 431 } 433 434 try { 435 new TCByteBufferOutputStream(-1, false); 436 fail(); 437 } catch (IllegalArgumentException iae) { 438 } 440 441 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(); 442 try { 443 bbos.write((byte[]) null); 444 fail(); 445 } catch (NullPointerException npe) { 446 } 448 449 try { 450 bbos.write((TCByteBuffer[]) null); 451 fail(); 452 } catch (NullPointerException npe) { 453 } 455 456 try { 457 bbos.write(null, 0, 0); 458 fail(); 459 } catch (NullPointerException npe) { 460 } 462 463 try { 464 bbos.write(new byte[10], -10, 0); 465 fail(); 466 } catch (IndexOutOfBoundsException ioobe) { 467 } 469 470 try { 471 bbos.write(new byte[10], 1, -10); 472 fail(); 473 } catch (IndexOutOfBoundsException ioobe) { 474 } 476 477 try { 478 bbos.write(new byte[10], 1, 10); 479 fail(); 480 } catch (IndexOutOfBoundsException ioobe) { 481 } 483 } 484 485 public void testEdgeCase1() { 486 testEdgeCase(10, 5, 1004); 487 } 488 489 private void testEdgeCase(int bufLength, int byteArrLength, int iterationCount) { 490 491 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(bufLength, false); 492 byte data[] = new byte[byteArrLength]; 493 494 int dataWriten = 0; 495 for (int i = 0; i < iterationCount; i++) { 496 bbos.write(data); 497 dataWriten += data.length; 498 } 499 500 TCByteBuffer[] bufs = bbos.toArray(); 501 for (int i = 0; i < bufs.length - 1; i++) { 502 assertEquals(bufs[i].capacity(), bufs[i].limit()); 503 dataWriten -= bufs[i].limit(); 504 } 505 assertEquals(dataWriten, bufs[bufs.length - 1].limit()); 506 } 507 508 public void testEdgeCase2() { 509 testEdgeCase(3, 37, 10); 510 } 511 512 public void testEdgeCase3() { 513 testEdgeCase(1, 1, 5000); 514 } 515 516 public void testEdgeCase4() { 517 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(27, false); 518 byte data[] = new byte[370]; 519 520 int written = 0; 521 for (int i = 0; i < 50; i++) { 522 Arrays.fill(data, (byte) 0); 523 Arrays.fill(data, i, i + 50, (byte) 42); 524 bbos.write(data, i, 50); 525 written += 50; 526 } 527 528 TCByteBuffer[] bufs = bbos.toArray(); 529 for (int i = 0; i < bufs.length - 1; i++) { 530 assertEquals(bufs[i].capacity(), bufs[i].limit()); 531 written -= bufs[i].limit(); 532 } 533 assertEquals(written, bufs[bufs.length-1].limit()); 534 535 for (int i = 0; i < bufs.length; i++) { 536 while (bufs[i].hasRemaining()) { 537 assertEquals(42, bufs[i].get()); 538 } 539 } 540 } 541 542 public void testEmpty() { 543 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(); 544 bbos.close(); 545 TCByteBuffer[] data = bbos.toArray(); 546 assertEquals(0, data.length); 547 } 548 549 public void testClose() { 550 TCByteBufferOutputStream bbos = new TCByteBufferOutputStream(); 551 552 bbos.write(new byte[1234]); 553 for (int i = 0; i < 10; i++) { 554 bbos.close(); 555 } 556 557 try { 558 bbos.write(1); 559 fail(); 560 } catch (IllegalStateException ise) { 561 } 563 564 try { 565 bbos.write(new byte[10]); 566 fail(); 567 } catch (IllegalStateException ise) { 568 } 570 571 try { 572 bbos.write(new byte[10], 2, 5); 573 fail(); 574 } catch (IllegalStateException ise) { 575 } 577 578 try { 579 bbos.write(new TCByteBuffer[] {}); 580 fail(); 581 } catch (IllegalStateException ise) { 582 } 584 585 } 586 } 587 | Popular Tags |