1 /* 2 * Copyright (C) 2007 The Guava Authors 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 com.google.common.io; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 22 import com.google.common.base.Charsets; 23 import java.io.ByteArrayInputStream; 24 import java.io.ByteArrayOutputStream; 25 import java.io.EOFException; 26 import java.io.File; 27 import java.io.FileOutputStream; 28 import java.io.FilterInputStream; 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.io.OutputStream; 32 import java.io.RandomAccessFile; 33 import java.nio.channels.Channels; 34 import java.nio.channels.ReadableByteChannel; 35 import java.nio.channels.WritableByteChannel; 36 import java.util.Arrays; 37 38 /** 39 * Unit test for {@link ByteStreams}. 40 * 41 * @author Chris Nokleberg 42 */ 43 public class ByteStreamsTest extends IoTestCase { 44 testCopyChannel()45 public void testCopyChannel() throws IOException { 46 byte[] expected = newPreFilledByteArray(100); 47 ByteArrayOutputStream out = new ByteArrayOutputStream(); 48 WritableByteChannel outChannel = Channels.newChannel(out); 49 50 ReadableByteChannel inChannel = Channels.newChannel(new ByteArrayInputStream(expected)); 51 ByteStreams.copy(inChannel, outChannel); 52 assertThat(out.toByteArray()).isEqualTo(expected); 53 } 54 55 testCopyFileChannel()56 public void testCopyFileChannel() throws IOException { 57 final int chunkSize = 14407; // Random prime, unlikely to match any internal chunk size 58 ByteArrayOutputStream out = new ByteArrayOutputStream(); 59 WritableByteChannel outChannel = Channels.newChannel(out); 60 61 File testFile = createTempFile(); 62 byte[] dummyData = newPreFilledByteArray(chunkSize); 63 try (FileOutputStream fos = new FileOutputStream(testFile)) { 64 for (int i = 0; i < 500; i++) { 65 fos.write(dummyData); 66 } 67 } 68 try (ReadableByteChannel inChannel = new RandomAccessFile(testFile, "r").getChannel()) { 69 ByteStreams.copy(inChannel, outChannel); 70 } 71 byte[] actual = out.toByteArray(); 72 for (int i = 0; i < 500 * chunkSize; i += chunkSize) { 73 assertThat(Arrays.copyOfRange(actual, i, i + chunkSize)).isEqualTo(dummyData); 74 } 75 } 76 testReadFully()77 public void testReadFully() throws IOException { 78 byte[] b = new byte[10]; 79 80 assertThrows( 81 NullPointerException.class, () -> ByteStreams.readFully(newTestStream(10), null, 0, 10)); 82 83 assertThrows(NullPointerException.class, () -> ByteStreams.readFully(null, b, 0, 10)); 84 85 assertThrows( 86 IndexOutOfBoundsException.class, () -> ByteStreams.readFully(newTestStream(10), b, -1, 10)); 87 88 assertThrows( 89 IndexOutOfBoundsException.class, () -> ByteStreams.readFully(newTestStream(10), b, 0, -1)); 90 91 assertThrows( 92 IndexOutOfBoundsException.class, () -> ByteStreams.readFully(newTestStream(10), b, 0, -1)); 93 94 assertThrows( 95 IndexOutOfBoundsException.class, () -> ByteStreams.readFully(newTestStream(10), b, 2, 10)); 96 97 assertThrows(EOFException.class, () -> ByteStreams.readFully(newTestStream(5), b, 0, 10)); 98 99 Arrays.fill(b, (byte) 0); 100 ByteStreams.readFully(newTestStream(10), b, 0, 0); 101 assertThat(b).isEqualTo(new byte[10]); 102 103 Arrays.fill(b, (byte) 0); 104 ByteStreams.readFully(newTestStream(10), b, 0, 10); 105 assertThat(b).isEqualTo(newPreFilledByteArray(10)); 106 107 Arrays.fill(b, (byte) 0); 108 ByteStreams.readFully(newTestStream(10), b, 0, 5); 109 assertThat(b).isEqualTo(new byte[] {0, 1, 2, 3, 4, 0, 0, 0, 0, 0}); 110 } 111 testSkipFully()112 public void testSkipFully() throws IOException { 113 byte[] bytes = newPreFilledByteArray(100); 114 skipHelper(0, 0, new ByteArrayInputStream(bytes)); 115 skipHelper(50, 50, new ByteArrayInputStream(bytes)); 116 skipHelper(50, 50, new SlowSkipper(new ByteArrayInputStream(bytes), 1)); 117 skipHelper(50, 50, new SlowSkipper(new ByteArrayInputStream(bytes), 0)); 118 skipHelper(100, -1, new ByteArrayInputStream(bytes)); 119 assertThrows(EOFException.class, () -> skipHelper(101, 0, new ByteArrayInputStream(bytes))); 120 } 121 skipHelper(long n, int expect, InputStream in)122 private static void skipHelper(long n, int expect, InputStream in) throws IOException { 123 ByteStreams.skipFully(in, n); 124 assertEquals(expect, in.read()); 125 in.close(); 126 } 127 128 private static final byte[] bytes = new byte[] {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10}; 129 testNewDataInput_empty()130 public void testNewDataInput_empty() { 131 byte[] b = new byte[0]; 132 ByteArrayDataInput in = ByteStreams.newDataInput(b); 133 assertThrows(IllegalStateException.class, () -> in.readInt()); 134 } 135 testNewDataInput_normal()136 public void testNewDataInput_normal() { 137 ByteArrayDataInput in = ByteStreams.newDataInput(bytes); 138 assertEquals(0x12345678, in.readInt()); 139 assertEquals(0x76543210, in.readInt()); 140 assertThrows(IllegalStateException.class, () -> in.readInt()); 141 } 142 testNewDataInput_readFully()143 public void testNewDataInput_readFully() { 144 ByteArrayDataInput in = ByteStreams.newDataInput(bytes); 145 byte[] actual = new byte[bytes.length]; 146 in.readFully(actual); 147 assertThat(actual).isEqualTo(bytes); 148 } 149 testNewDataInput_readFullyAndThenSome()150 public void testNewDataInput_readFullyAndThenSome() { 151 ByteArrayDataInput in = ByteStreams.newDataInput(bytes); 152 byte[] actual = new byte[bytes.length * 2]; 153 IllegalStateException ex = 154 assertThrows(IllegalStateException.class, () -> in.readFully(actual)); 155 assertThat(ex).hasCauseThat().isInstanceOf(EOFException.class); 156 } 157 testNewDataInput_readFullyWithOffset()158 public void testNewDataInput_readFullyWithOffset() { 159 ByteArrayDataInput in = ByteStreams.newDataInput(bytes); 160 byte[] actual = new byte[4]; 161 in.readFully(actual, 2, 2); 162 assertEquals(0, actual[0]); 163 assertEquals(0, actual[1]); 164 assertEquals(bytes[0], actual[2]); 165 assertEquals(bytes[1], actual[3]); 166 } 167 testNewDataInput_readLine()168 public void testNewDataInput_readLine() { 169 ByteArrayDataInput in = 170 ByteStreams.newDataInput( 171 "This is a line\r\nThis too\rand this\nand also this".getBytes(Charsets.UTF_8)); 172 assertEquals("This is a line", in.readLine()); 173 assertEquals("This too", in.readLine()); 174 assertEquals("and this", in.readLine()); 175 assertEquals("and also this", in.readLine()); 176 } 177 testNewDataInput_readFloat()178 public void testNewDataInput_readFloat() { 179 byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10}; 180 ByteArrayDataInput in = ByteStreams.newDataInput(data); 181 assertEquals(Float.intBitsToFloat(0x12345678), in.readFloat(), 0.0); 182 assertEquals(Float.intBitsToFloat(0x76543210), in.readFloat(), 0.0); 183 } 184 testNewDataInput_readDouble()185 public void testNewDataInput_readDouble() { 186 byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10}; 187 ByteArrayDataInput in = ByteStreams.newDataInput(data); 188 assertEquals(Double.longBitsToDouble(0x1234567876543210L), in.readDouble(), 0.0); 189 } 190 testNewDataInput_readUTF()191 public void testNewDataInput_readUTF() { 192 byte[] data = new byte[17]; 193 data[1] = 15; 194 System.arraycopy("Kilroy was here".getBytes(Charsets.UTF_8), 0, data, 2, 15); 195 ByteArrayDataInput in = ByteStreams.newDataInput(data); 196 assertEquals("Kilroy was here", in.readUTF()); 197 } 198 testNewDataInput_readChar()199 public void testNewDataInput_readChar() { 200 byte[] data = "qed".getBytes(Charsets.UTF_16BE); 201 ByteArrayDataInput in = ByteStreams.newDataInput(data); 202 assertEquals('q', in.readChar()); 203 assertEquals('e', in.readChar()); 204 assertEquals('d', in.readChar()); 205 } 206 testNewDataInput_readUnsignedShort()207 public void testNewDataInput_readUnsignedShort() { 208 byte[] data = {0, 0, 0, 1, (byte) 0xFF, (byte) 0xFF, 0x12, 0x34}; 209 ByteArrayDataInput in = ByteStreams.newDataInput(data); 210 assertEquals(0, in.readUnsignedShort()); 211 assertEquals(1, in.readUnsignedShort()); 212 assertEquals(65535, in.readUnsignedShort()); 213 assertEquals(0x1234, in.readUnsignedShort()); 214 } 215 testNewDataInput_readLong()216 public void testNewDataInput_readLong() { 217 byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10}; 218 ByteArrayDataInput in = ByteStreams.newDataInput(data); 219 assertEquals(0x1234567876543210L, in.readLong()); 220 } 221 testNewDataInput_readBoolean()222 public void testNewDataInput_readBoolean() { 223 ByteArrayDataInput in = ByteStreams.newDataInput(bytes); 224 assertTrue(in.readBoolean()); 225 } 226 testNewDataInput_readByte()227 public void testNewDataInput_readByte() { 228 ByteArrayDataInput in = ByteStreams.newDataInput(bytes); 229 for (byte aByte : bytes) { 230 assertEquals(aByte, in.readByte()); 231 } 232 IllegalStateException expected = assertThrows(IllegalStateException.class, () -> in.readByte()); 233 assertThat(expected).hasCauseThat().isInstanceOf(EOFException.class); 234 } 235 testNewDataInput_readUnsignedByte()236 public void testNewDataInput_readUnsignedByte() { 237 ByteArrayDataInput in = ByteStreams.newDataInput(bytes); 238 for (byte aByte : bytes) { 239 assertEquals(aByte, in.readUnsignedByte()); 240 } 241 IllegalStateException expected = 242 assertThrows(IllegalStateException.class, () -> in.readUnsignedByte()); 243 assertThat(expected).hasCauseThat().isInstanceOf(EOFException.class); 244 } 245 testNewDataInput_offset()246 public void testNewDataInput_offset() { 247 ByteArrayDataInput in = ByteStreams.newDataInput(bytes, 2); 248 assertEquals(0x56787654, in.readInt()); 249 assertThrows(IllegalStateException.class, () -> in.readInt()); 250 } 251 testNewDataInput_skip()252 public void testNewDataInput_skip() { 253 ByteArrayDataInput in = ByteStreams.newDataInput(new byte[2]); 254 assertEquals(2, in.skipBytes(2)); 255 assertEquals(0, in.skipBytes(1)); 256 } 257 testNewDataInput_BAIS()258 public void testNewDataInput_BAIS() { 259 ByteArrayInputStream bais = new ByteArrayInputStream(new byte[] {0x12, 0x34, 0x56, 0x78}); 260 ByteArrayDataInput in = ByteStreams.newDataInput(bais); 261 assertEquals(0x12345678, in.readInt()); 262 } 263 testNewDataOutput_empty()264 public void testNewDataOutput_empty() { 265 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 266 assertEquals(0, out.toByteArray().length); 267 } 268 testNewDataOutput_writeInt()269 public void testNewDataOutput_writeInt() { 270 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 271 out.writeInt(0x12345678); 272 out.writeInt(0x76543210); 273 assertThat(out.toByteArray()).isEqualTo(bytes); 274 } 275 testNewDataOutput_sized()276 public void testNewDataOutput_sized() { 277 ByteArrayDataOutput out = ByteStreams.newDataOutput(4); 278 out.writeInt(0x12345678); 279 out.writeInt(0x76543210); 280 assertThat(out.toByteArray()).isEqualTo(bytes); 281 } 282 testNewDataOutput_writeLong()283 public void testNewDataOutput_writeLong() { 284 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 285 out.writeLong(0x1234567876543210L); 286 assertThat(out.toByteArray()).isEqualTo(bytes); 287 } 288 testNewDataOutput_writeByteArray()289 public void testNewDataOutput_writeByteArray() { 290 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 291 out.write(bytes); 292 assertThat(out.toByteArray()).isEqualTo(bytes); 293 } 294 testNewDataOutput_writeByte()295 public void testNewDataOutput_writeByte() { 296 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 297 out.write(0x12); 298 out.writeByte(0x34); 299 assertThat(out.toByteArray()).isEqualTo(new byte[] {0x12, 0x34}); 300 } 301 testNewDataOutput_writeByteOffset()302 public void testNewDataOutput_writeByteOffset() { 303 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 304 out.write(bytes, 4, 2); 305 byte[] expected = {bytes[4], bytes[5]}; 306 assertThat(out.toByteArray()).isEqualTo(expected); 307 } 308 testNewDataOutput_writeBoolean()309 public void testNewDataOutput_writeBoolean() { 310 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 311 out.writeBoolean(true); 312 out.writeBoolean(false); 313 byte[] expected = {(byte) 1, (byte) 0}; 314 assertThat(out.toByteArray()).isEqualTo(expected); 315 } 316 testNewDataOutput_writeChar()317 public void testNewDataOutput_writeChar() { 318 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 319 out.writeChar('a'); 320 assertThat(out.toByteArray()).isEqualTo(new byte[] {0, 97}); 321 } 322 323 // Hardcoded because of Android problems. See testUtf16Expected. 324 private static final byte[] utf16ExpectedWithBom = 325 new byte[] {-2, -1, 0, 114, 0, -55, 0, 115, 0, 117, 0, 109, 0, -55}; 326 testNewDataOutput_writeChars()327 public void testNewDataOutput_writeChars() { 328 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 329 out.writeChars("r\u00C9sum\u00C9"); 330 // need to remove byte order mark before comparing 331 byte[] expected = Arrays.copyOfRange(utf16ExpectedWithBom, 2, 14); 332 assertThat(out.toByteArray()).isEqualTo(expected); 333 } 334 335 @AndroidIncompatible // https://issuetracker.google.com/issues/37074504 testUtf16Expected()336 public void testUtf16Expected() { 337 byte[] hardcodedExpected = utf16ExpectedWithBom; 338 byte[] computedExpected = "r\u00C9sum\u00C9".getBytes(Charsets.UTF_16); 339 assertThat(computedExpected).isEqualTo(hardcodedExpected); 340 } 341 testNewDataOutput_writeUTF()342 public void testNewDataOutput_writeUTF() { 343 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 344 out.writeUTF("r\u00C9sum\u00C9"); 345 byte[] expected = "r\u00C9sum\u00C9".getBytes(Charsets.UTF_8); 346 byte[] actual = out.toByteArray(); 347 // writeUTF writes the length of the string in 2 bytes 348 assertEquals(0, actual[0]); 349 assertEquals(expected.length, actual[1]); 350 assertThat(Arrays.copyOfRange(actual, 2, actual.length)).isEqualTo(expected); 351 } 352 testNewDataOutput_writeShort()353 public void testNewDataOutput_writeShort() { 354 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 355 out.writeShort(0x1234); 356 assertThat(out.toByteArray()).isEqualTo(new byte[] {0x12, 0x34}); 357 } 358 testNewDataOutput_writeDouble()359 public void testNewDataOutput_writeDouble() { 360 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 361 out.writeDouble(Double.longBitsToDouble(0x1234567876543210L)); 362 assertThat(out.toByteArray()).isEqualTo(bytes); 363 } 364 testNewDataOutput_writeFloat()365 public void testNewDataOutput_writeFloat() { 366 ByteArrayDataOutput out = ByteStreams.newDataOutput(); 367 out.writeFloat(Float.intBitsToFloat(0x12345678)); 368 out.writeFloat(Float.intBitsToFloat(0x76543210)); 369 assertThat(out.toByteArray()).isEqualTo(bytes); 370 } 371 testNewDataOutput_BAOS()372 public void testNewDataOutput_BAOS() { 373 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 374 ByteArrayDataOutput out = ByteStreams.newDataOutput(baos); 375 out.writeInt(0x12345678); 376 assertEquals(4, baos.size()); 377 assertThat(baos.toByteArray()).isEqualTo(new byte[] {0x12, 0x34, 0x56, 0x78}); 378 } 379 380 private static final byte[] PRE_FILLED_100 = newPreFilledByteArray(100); 381 testToByteArray()382 public void testToByteArray() throws IOException { 383 InputStream in = new ByteArrayInputStream(PRE_FILLED_100); 384 byte[] b = ByteStreams.toByteArray(in); 385 assertThat(b).isEqualTo(PRE_FILLED_100); 386 } 387 testToByteArray_emptyStream()388 public void testToByteArray_emptyStream() throws IOException { 389 InputStream in = newTestStream(0); 390 byte[] b = ByteStreams.toByteArray(in); 391 assertThat(b).isEqualTo(new byte[0]); 392 } 393 testToByteArray_largeStream()394 public void testToByteArray_largeStream() throws IOException { 395 // well, large enough to require multiple buffers 396 byte[] expected = newPreFilledByteArray(10000000); 397 InputStream in = new ByteArrayInputStream(expected); 398 byte[] b = ByteStreams.toByteArray(in); 399 assertThat(b).isEqualTo(expected); 400 } 401 testToByteArray_withSize_givenCorrectSize()402 public void testToByteArray_withSize_givenCorrectSize() throws IOException { 403 InputStream in = new ByteArrayInputStream(PRE_FILLED_100); 404 byte[] b = ByteStreams.toByteArray(in, 100); 405 assertThat(b).isEqualTo(PRE_FILLED_100); 406 } 407 testToByteArray_withSize_givenSmallerSize()408 public void testToByteArray_withSize_givenSmallerSize() throws IOException { 409 InputStream in = new ByteArrayInputStream(PRE_FILLED_100); 410 byte[] b = ByteStreams.toByteArray(in, 80); 411 assertThat(b).isEqualTo(PRE_FILLED_100); 412 } 413 testToByteArray_withSize_givenLargerSize()414 public void testToByteArray_withSize_givenLargerSize() throws IOException { 415 InputStream in = new ByteArrayInputStream(PRE_FILLED_100); 416 byte[] b = ByteStreams.toByteArray(in, 120); 417 assertThat(b).isEqualTo(PRE_FILLED_100); 418 } 419 testToByteArray_withSize_givenSizeZero()420 public void testToByteArray_withSize_givenSizeZero() throws IOException { 421 InputStream in = new ByteArrayInputStream(PRE_FILLED_100); 422 byte[] b = ByteStreams.toByteArray(in, 0); 423 assertThat(b).isEqualTo(PRE_FILLED_100); 424 } 425 testToByteArray_withSize_givenSizeOneSmallerThanActual()426 public void testToByteArray_withSize_givenSizeOneSmallerThanActual() throws IOException { 427 InputStream in = new ByteArrayInputStream(PRE_FILLED_100); 428 // this results in toByteArrayInternal being called when the stream is actually exhausted 429 byte[] b = ByteStreams.toByteArray(in, 99); 430 assertThat(b).isEqualTo(PRE_FILLED_100); 431 } 432 testToByteArray_withSize_givenSizeTwoSmallerThanActual()433 public void testToByteArray_withSize_givenSizeTwoSmallerThanActual() throws IOException { 434 InputStream in = new ByteArrayInputStream(PRE_FILLED_100); 435 byte[] b = ByteStreams.toByteArray(in, 98); 436 assertThat(b).isEqualTo(PRE_FILLED_100); 437 } 438 testExhaust()439 public void testExhaust() throws IOException { 440 InputStream in = newTestStream(100); 441 assertEquals(100, ByteStreams.exhaust(in)); 442 assertEquals(-1, in.read()); 443 assertEquals(0, ByteStreams.exhaust(in)); 444 445 InputStream empty = newTestStream(0); 446 assertEquals(0, ByteStreams.exhaust(empty)); 447 assertEquals(-1, empty.read()); 448 } 449 newTestStream(int n)450 private static InputStream newTestStream(int n) { 451 return new ByteArrayInputStream(newPreFilledByteArray(n)); 452 } 453 454 /** Stream that will skip a maximum number of bytes at a time. */ 455 private static class SlowSkipper extends FilterInputStream { 456 private final long max; 457 SlowSkipper(InputStream in, long max)458 SlowSkipper(InputStream in, long max) { 459 super(in); 460 this.max = max; 461 } 462 463 @Override skip(long n)464 public long skip(long n) throws IOException { 465 return super.skip(Math.min(max, n)); 466 } 467 } 468 testReadBytes()469 public void testReadBytes() throws IOException { 470 final byte[] array = newPreFilledByteArray(1000); 471 assertThat(ByteStreams.readBytes(new ByteArrayInputStream(array), new TestByteProcessor())) 472 .isEqualTo(array); 473 } 474 475 private static class TestByteProcessor implements ByteProcessor<byte[]> { 476 private final ByteArrayOutputStream out = new ByteArrayOutputStream(); 477 478 @Override processBytes(byte[] buf, int off, int len)479 public boolean processBytes(byte[] buf, int off, int len) { 480 out.write(buf, off, len); 481 return true; 482 } 483 484 @Override getResult()485 public byte[] getResult() { 486 return out.toByteArray(); 487 } 488 } 489 testByteProcessorStopEarly()490 public void testByteProcessorStopEarly() throws IOException { 491 byte[] array = newPreFilledByteArray(10000); 492 assertEquals( 493 (Integer) 42, 494 ByteStreams.readBytes( 495 new ByteArrayInputStream(array), 496 new ByteProcessor<Integer>() { 497 @Override 498 public boolean processBytes(byte[] buf, int off, int len) { 499 assertThat(newPreFilledByteArray(8192)) 500 .isEqualTo(Arrays.copyOfRange(buf, off, off + len)); 501 return false; 502 } 503 504 @Override 505 public Integer getResult() { 506 return 42; 507 } 508 })); 509 } 510 testNullOutputStream()511 public void testNullOutputStream() throws Exception { 512 // create a null output stream 513 OutputStream nos = ByteStreams.nullOutputStream(); 514 // write to the output stream 515 nos.write('n'); 516 String test = "Test string for NullOutputStream"; 517 byte[] bytes = test.getBytes(Charsets.US_ASCII); 518 nos.write(bytes); 519 nos.write(bytes, 2, 10); 520 nos.write(bytes, bytes.length - 5, 5); 521 // nothing really to assert? 522 assertSame(ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream()); 523 } 524 testNullOutputStream_exceptions()525 public void testNullOutputStream_exceptions() throws Exception { 526 OutputStream nos = ByteStreams.nullOutputStream(); 527 assertThrows(NullPointerException.class, () -> nos.write(null)); 528 assertThrows(NullPointerException.class, () -> nos.write(null, 0, 1)); 529 byte[] tenBytes = new byte[10]; 530 assertThrows(IndexOutOfBoundsException.class, () -> nos.write(tenBytes, -1, 1)); 531 assertThrows(IndexOutOfBoundsException.class, () -> nos.write(tenBytes, 1, -1)); 532 assertThrows(IndexOutOfBoundsException.class, () -> nos.write(tenBytes, 9, 2)); 533 assertThrows(IndexOutOfBoundsException.class, () -> nos.write(tenBytes, 9, 100)); 534 } 535 testLimit()536 public void testLimit() throws Exception { 537 byte[] big = newPreFilledByteArray(5); 538 InputStream bin = new ByteArrayInputStream(big); 539 InputStream lin = ByteStreams.limit(bin, 2); 540 541 // also test available 542 lin.mark(2); 543 assertEquals(2, lin.available()); 544 int read = lin.read(); 545 assertEquals(big[0], read); 546 assertEquals(1, lin.available()); 547 read = lin.read(); 548 assertEquals(big[1], read); 549 assertEquals(0, lin.available()); 550 read = lin.read(); 551 assertEquals(-1, read); 552 553 lin.reset(); 554 byte[] small = new byte[5]; 555 read = lin.read(small); 556 assertEquals(2, read); 557 assertEquals(big[0], small[0]); 558 assertEquals(big[1], small[1]); 559 560 lin.reset(); 561 read = lin.read(small, 2, 3); 562 assertEquals(2, read); 563 assertEquals(big[0], small[2]); 564 assertEquals(big[1], small[3]); 565 } 566 testLimit_mark()567 public void testLimit_mark() throws Exception { 568 byte[] big = newPreFilledByteArray(5); 569 InputStream bin = new ByteArrayInputStream(big); 570 InputStream lin = ByteStreams.limit(bin, 2); 571 572 int read = lin.read(); 573 assertEquals(big[0], read); 574 lin.mark(2); 575 576 read = lin.read(); 577 assertEquals(big[1], read); 578 read = lin.read(); 579 assertEquals(-1, read); 580 581 lin.reset(); 582 read = lin.read(); 583 assertEquals(big[1], read); 584 read = lin.read(); 585 assertEquals(-1, read); 586 } 587 testLimit_skip()588 public void testLimit_skip() throws Exception { 589 byte[] big = newPreFilledByteArray(5); 590 InputStream bin = new ByteArrayInputStream(big); 591 InputStream lin = ByteStreams.limit(bin, 2); 592 593 // also test available 594 lin.mark(2); 595 assertEquals(2, lin.available()); 596 lin.skip(1); 597 assertEquals(1, lin.available()); 598 599 lin.reset(); 600 assertEquals(2, lin.available()); 601 lin.skip(3); 602 assertEquals(0, lin.available()); 603 } 604 testLimit_markNotSet()605 public void testLimit_markNotSet() { 606 byte[] big = newPreFilledByteArray(5); 607 InputStream bin = new ByteArrayInputStream(big); 608 InputStream lin = ByteStreams.limit(bin, 2); 609 610 IOException expected = assertThrows(IOException.class, () -> lin.reset()); 611 assertThat(expected).hasMessageThat().isEqualTo("Mark not set"); 612 } 613 testLimit_markNotSupported()614 public void testLimit_markNotSupported() { 615 InputStream lin = ByteStreams.limit(new UnmarkableInputStream(), 2); 616 617 IOException expected = assertThrows(IOException.class, () -> lin.reset()); 618 assertThat(expected).hasMessageThat().isEqualTo("Mark not supported"); 619 } 620 621 private static class UnmarkableInputStream extends InputStream { 622 @Override read()623 public int read() throws IOException { 624 return 0; 625 } 626 627 @Override markSupported()628 public boolean markSupported() { 629 return false; 630 } 631 } 632 } 633