1 /* 2 * Copyright (C) 2016 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 libcore.libcore.io; 18 19 import junit.framework.TestCase; 20 21 import android.system.ErrnoException; 22 import android.system.OsConstants; 23 24 import java.io.File; 25 import java.io.FileOutputStream; 26 import java.nio.ByteBuffer; 27 import java.nio.ByteOrder; 28 import java.nio.IntBuffer; 29 import java.util.Arrays; 30 import java.util.function.Function; 31 import libcore.io.BufferIterator; 32 import libcore.io.MemoryMappedFile; 33 import libcore.testing.io.TestIoUtils; 34 35 public class MemoryMappedFileTest extends TestCase { 36 37 private File tempDir; 38 39 @Override setUp()40 public void setUp() throws Exception { 41 super.setUp(); 42 tempDir = TestIoUtils.createTemporaryDirectory("MemoryMappedFileTest"); 43 } 44 testMmapRo_missingFile()45 public void testMmapRo_missingFile() throws Exception { 46 try { 47 MemoryMappedFile.mmapRO("doesNotExist"); 48 fail(); 49 } catch (ErrnoException e) { 50 assertEquals(OsConstants.ENOENT, e.errno); 51 } 52 } 53 testMmapRo_emptyFile()54 public void testMmapRo_emptyFile() throws Exception { 55 byte[] bytes = new byte[0]; 56 File file = createFile(bytes); 57 try { 58 MemoryMappedFile.mmapRO(file.getPath()); 59 fail(); 60 } catch (ErrnoException e) { 61 assertEquals(OsConstants.EINVAL, e.errno); 62 } finally { 63 file.delete(); 64 } 65 } 66 testMmapRo()67 public void testMmapRo() throws Exception { 68 byte[] bytes = createBytes(10); 69 File file = createFile(bytes); 70 try (MemoryMappedFile memoryMappedFile = MemoryMappedFile.mmapRO(file.getPath())) { 71 assertEquals(10, memoryMappedFile.size()); 72 } finally { 73 file.delete(); 74 } 75 } 76 testMmapRo_close()77 public void testMmapRo_close() throws Exception { 78 byte[] bytes = createBytes(10); 79 File file = createFile(bytes); 80 MemoryMappedFile memoryMappedFile = MemoryMappedFile.mmapRO(file.getPath()); 81 memoryMappedFile.close(); 82 83 try { 84 memoryMappedFile.bigEndianIterator(); 85 fail(); 86 } catch (IllegalStateException expected) { 87 } 88 89 try { 90 memoryMappedFile.littleEndianIterator(); 91 fail(); 92 } catch (IllegalStateException expected) { 93 } 94 95 // Should not have any effect. 96 memoryMappedFile.close(); 97 } 98 testReadAfterCloseFails()99 public void testReadAfterCloseFails() throws Exception { 100 byte[] bytes = createBytes(10); 101 File file = createFile(bytes); 102 MemoryMappedFile memoryMappedFile = MemoryMappedFile.mmapRO(file.getPath()); 103 BufferIterator iterator = memoryMappedFile.bigEndianIterator(); 104 memoryMappedFile.close(); 105 106 try { 107 iterator.readByte(); 108 fail(); 109 } catch (IllegalStateException expected) {} 110 } 111 testReadByte()112 public void testReadByte() throws Exception { 113 checkReadByte(MemoryMappedFile::bigEndianIterator); 114 checkReadByte(MemoryMappedFile::littleEndianIterator); 115 } 116 checkReadByte( Function<MemoryMappedFile, BufferIterator> iteratorFactory)117 private void checkReadByte( 118 Function<MemoryMappedFile, BufferIterator> iteratorFactory) throws Exception { 119 120 byte[] bytes = createBytes(10); 121 File file = createFile(bytes); 122 try { 123 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 124 BufferIterator iterator = iteratorFactory.apply(mappedFile); 125 for (int i = 0; i < bytes.length; i++) { 126 assertReadByteSucceeds(iterator, bytes[i]); 127 } 128 129 // Check skip. 130 iterator.seek(0); 131 for (int i = 0; i < bytes.length; i += 2) { 132 assertReadByteSucceeds(iterator, bytes[i]); 133 iterator.skip(1); 134 } 135 } finally { 136 file.delete(); 137 } 138 } 139 testSeek()140 public void testSeek() throws Exception { 141 checkSeek(MemoryMappedFile::bigEndianIterator); 142 checkSeek(MemoryMappedFile::littleEndianIterator); 143 } 144 checkSeek( Function<MemoryMappedFile, BufferIterator> iteratorFactory)145 private void checkSeek( 146 Function<MemoryMappedFile, BufferIterator> iteratorFactory) throws Exception { 147 148 byte[] bytes = createBytes(10); 149 File file = createFile(bytes); 150 try { 151 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 152 BufferIterator iterator = iteratorFactory.apply(mappedFile); 153 seekRead(bytes, iterator, 2); 154 155 seekRead(bytes, iterator, 0); 156 157 seekRead(bytes, iterator, 1); 158 159 seekRead(bytes, iterator, 9); 160 161 seekReadExpectFailure(iterator, -1); 162 163 seekRead(bytes, iterator, 1); 164 165 seekReadExpectFailure(iterator, 10); 166 seekReadExpectFailure(iterator, Integer.MAX_VALUE); 167 seekReadExpectFailure(iterator, Integer.MIN_VALUE); 168 } finally { 169 file.delete(); 170 } 171 } 172 seekRead(byte[] bytes, BufferIterator iterator, int offset)173 private static void seekRead(byte[] bytes, BufferIterator iterator, int offset) { 174 iterator.seek(offset); 175 assertEquals(offset, iterator.pos()); 176 assertReadByteSucceeds(iterator, bytes[offset]); 177 } 178 seekReadExpectFailure(BufferIterator iterator, int offset)179 private static void seekReadExpectFailure(BufferIterator iterator, int offset) { 180 iterator.seek(offset); 181 assertReadByteFails(iterator); 182 } 183 testSkip()184 public void testSkip() throws Exception { 185 checkSkip(MemoryMappedFile::bigEndianIterator); 186 checkSkip(MemoryMappedFile::littleEndianIterator); 187 } 188 checkSkip( Function<MemoryMappedFile, BufferIterator> iteratorFactory)189 private void checkSkip( 190 Function<MemoryMappedFile, BufferIterator> iteratorFactory) throws Exception { 191 192 byte[] bytes = createBytes(10); 193 File file = createFile(bytes); 194 try { 195 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 196 BufferIterator iterator = iteratorFactory.apply(mappedFile); 197 iterator.skip(1); 198 assertEquals(1, iterator.pos()); 199 assertReadByteSucceeds(iterator, bytes[1]); 200 201 iterator.skip(-1); 202 assertEquals(1, iterator.pos()); 203 assertReadByteSucceeds(iterator, bytes[1]); 204 205 iterator.skip(2); 206 assertEquals(4, iterator.pos()); 207 assertReadByteSucceeds(iterator, bytes[4]); 208 209 iterator.skip(-2); 210 assertEquals(3, iterator.pos()); 211 assertReadByteSucceeds(iterator, bytes[3]); 212 213 iterator.skip(3); 214 assertEquals(7, iterator.pos()); 215 assertReadByteSucceeds(iterator, bytes[7]); 216 217 iterator.skip(-3); 218 assertEquals(5, iterator.pos()); 219 assertReadByteSucceeds(iterator, bytes[5]); 220 221 iterator.skip(4); 222 assertEquals(10, iterator.pos()); 223 assertReadByteFails(iterator); 224 225 iterator.skip(-1); 226 assertEquals(9, iterator.pos()); 227 assertReadByteSucceeds(iterator, bytes[9]); 228 } finally { 229 file.delete(); 230 } 231 } 232 testReadShort_bigEndian()233 public void testReadShort_bigEndian() throws Exception { 234 byte[] bytes = createBytes(10); 235 File file = createFile(bytes); 236 try { 237 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 238 BufferIterator iterator = mappedFile.bigEndianIterator(); 239 240 // Even offset 241 short expectedValue = (short) ((bytes[0] << 8) | bytes[1]); 242 assertReadShortSucceeds(iterator, expectedValue); 243 244 checkShortFailureCases(iterator); 245 246 // Odd offset. 247 iterator.seek(1); 248 expectedValue = (short) ((bytes[1] << 8) | bytes[2]); 249 assertReadShortSucceeds(iterator, expectedValue); 250 } finally { 251 file.delete(); 252 } 253 } 254 testReadShort_littleEndian()255 public void testReadShort_littleEndian() throws Exception { 256 byte[] bytes = createBytes(10); 257 File file = createFile(bytes); 258 try { 259 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 260 BufferIterator iterator = mappedFile.littleEndianIterator(); 261 262 // Even offset 263 short expectedValue = (short) ((bytes[1] << 8) | bytes[0]); 264 assertReadShortSucceeds(iterator, expectedValue); 265 266 checkShortFailureCases(iterator); 267 268 // Odd offset. 269 iterator.seek(1); 270 expectedValue = (short) ((bytes[2] << 8) | bytes[1]); 271 assertReadShortSucceeds(iterator, expectedValue); 272 } finally { 273 file.delete(); 274 } 275 } 276 checkShortFailureCases(BufferIterator iterator)277 private static void checkShortFailureCases(BufferIterator iterator) { 278 // Partly before bounds. 279 iterator.seek(-1); 280 assertReadShortFails(iterator); 281 282 // Entirely before bounds. 283 iterator.seek(-2); 284 assertReadShortFails(iterator); 285 286 // Partly after bounds. 287 iterator.seek(9); 288 assertReadShortFails(iterator); 289 290 // Entirely after bounds. 291 iterator.seek(10); 292 assertReadShortFails(iterator); 293 } 294 testReadInt_bigEndian()295 public void testReadInt_bigEndian() throws Exception { 296 byte[] bytes = createBytes(10); 297 File file = createFile(bytes); 298 try { 299 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 300 BufferIterator iterator = mappedFile.bigEndianIterator(); 301 302 // Even offset 303 int expectedValue = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; 304 assertReadIntSucceeds(iterator, expectedValue); 305 306 checkIntFailureCases(iterator); 307 308 // Odd offset. 309 iterator.seek(1); 310 expectedValue = (bytes[1] << 24) | (bytes[2] << 16) | (bytes[3] << 8) | bytes[4]; 311 assertReadIntSucceeds(iterator, expectedValue); 312 } finally { 313 file.delete(); 314 } 315 } 316 testReadInt_littleEndian()317 public void testReadInt_littleEndian() throws Exception { 318 byte[] bytes = createBytes(10); 319 File file = createFile(bytes); 320 try { 321 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 322 BufferIterator iterator = mappedFile.littleEndianIterator(); 323 324 // Even offset 325 int expectedValue = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; 326 assertReadIntSucceeds(iterator, expectedValue); 327 328 checkIntFailureCases(iterator); 329 330 // Odd offset. 331 iterator.seek(1); 332 expectedValue = (bytes[4] << 24) | (bytes[3] << 16) | (bytes[2] << 8) | bytes[1]; 333 assertReadIntSucceeds(iterator, expectedValue); 334 } finally { 335 file.delete(); 336 } 337 } 338 checkIntFailureCases(BufferIterator iterator)339 private static void checkIntFailureCases(BufferIterator iterator) { 340 // Partly before bounds. 341 iterator.seek(-1); 342 assertReadIntFails(iterator); 343 344 // Entirely before bounds. 345 iterator.seek(-4); 346 assertReadIntFails(iterator); 347 348 // Partly after bounds. 349 iterator.seek(7); 350 assertReadIntFails(iterator); 351 352 // Entirely after bounds. 353 iterator.seek(10); 354 assertReadIntFails(iterator); 355 } 356 testReadIntArray()357 public void testReadIntArray() throws Exception { 358 checkReadIntArray(MemoryMappedFile::bigEndianIterator, ByteOrder.BIG_ENDIAN); 359 checkReadIntArray(MemoryMappedFile::littleEndianIterator, ByteOrder.LITTLE_ENDIAN); 360 } 361 checkReadIntArray( Function<MemoryMappedFile, BufferIterator> iteratorFactory, ByteOrder byteOrdering)362 private void checkReadIntArray( 363 Function<MemoryMappedFile, BufferIterator> iteratorFactory, 364 ByteOrder byteOrdering) throws Exception { 365 366 byte[] testBytes = createBytes(12); 367 File file = createFile(testBytes); 368 try { 369 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 370 BufferIterator iterator = iteratorFactory.apply(mappedFile); 371 372 // Even offsets. 373 iterator.seek(4); 374 assertReadIntArraySucceeds(iterator, testBytes, byteOrdering, 2 /* intCount */); 375 376 iterator.seek(0); 377 assertReadIntArraySucceeds(iterator, testBytes, byteOrdering, 3 /* intCount */); 378 379 checkIntArrayZeroReadCases(iterator); 380 381 // Odd offsets. 382 iterator.seek(1); 383 assertReadIntArraySucceeds(iterator, testBytes, byteOrdering, 2 /* intCount */); 384 iterator.seek(3); 385 assertReadIntArraySucceeds(iterator, testBytes, byteOrdering, 2 /* intCount */); 386 } finally { 387 file.delete(); 388 } 389 } 390 checkIntArrayZeroReadCases(BufferIterator iterator)391 private static void checkIntArrayZeroReadCases(BufferIterator iterator) { 392 // Zero length reads do nothing. 393 int posBeforeRead = iterator.pos(); 394 int[] dstWithExistingValues = new int[] { 111, 222 }; 395 iterator.readIntArray(dstWithExistingValues, 0, 0); 396 assertEquals(posBeforeRead, iterator.pos()); 397 assertArrayEquals(new int[] { 111, 222 }, dstWithExistingValues); 398 399 try { 400 iterator.readIntArray(null, 0, 0); 401 fail(); 402 } catch (NullPointerException expected) { 403 } 404 assertEquals(posBeforeRead, iterator.pos()); 405 406 int[] dst = new int[2]; 407 408 // Partly before bounds. 409 iterator.seek(-1); 410 assertReadIntArrayFails(iterator, dst, 0, 1); 411 412 // Entirely before bounds. 413 iterator.seek(-2); 414 assertReadIntArrayFails(iterator, dst, 0, 1); 415 416 // Partly after bounds. 417 iterator.seek(9); 418 assertReadIntArrayFails(iterator, dst, 0, 1); 419 420 // Entirely after bounds. 421 iterator.seek(12); 422 assertReadIntArrayFails(iterator, dst, 0, 1); 423 424 // dst too small. 425 assertReadIntArrayFails(iterator, dst, 0, 3); // dst can only hold 2 ints 426 427 // offset leaves dst too small. 428 assertReadIntArrayFails(iterator, dst, 1, 2); 429 430 // Invalid offset 431 assertReadIntArrayFails(iterator, dst, -1, 2); 432 assertReadIntArrayFails(iterator, dst, 2, 2); 433 434 // Null dst 435 try { 436 iterator.readIntArray(null, 0, 1); 437 fail(); 438 } catch (NullPointerException expected) { 439 } 440 } 441 testReadByteArray()442 public void testReadByteArray() throws Exception { 443 checkReadByteArray(MemoryMappedFile::bigEndianIterator); 444 checkReadByteArray(MemoryMappedFile::littleEndianIterator); 445 } 446 checkReadByteArray( Function<MemoryMappedFile, BufferIterator> iteratorFactory)447 private void checkReadByteArray( 448 Function<MemoryMappedFile, BufferIterator> iteratorFactory) throws Exception { 449 450 byte[] testBytes = createBytes(12); 451 File file = createFile(testBytes); 452 try { 453 MemoryMappedFile mappedFile = MemoryMappedFile.mmapRO(file.getPath()); 454 BufferIterator iterator = iteratorFactory.apply(mappedFile); 455 456 // Even offsets. 457 iterator.seek(4); 458 assertReadByteArraySucceeds(iterator, testBytes, 2 /* intCount */); 459 460 iterator.seek(0); 461 assertReadByteArraySucceeds(iterator, testBytes, 3 /* intCount */); 462 463 checkByteArrayZeroReadCases(iterator); 464 465 // Odd offsets. 466 iterator.seek(1); 467 assertReadByteArraySucceeds(iterator, testBytes, 2 /* intCount */); 468 iterator.seek(3); 469 assertReadByteArraySucceeds(iterator, testBytes, 2 /* intCount */); 470 } finally { 471 file.delete(); 472 } 473 } 474 checkByteArrayZeroReadCases(BufferIterator iterator)475 private static void checkByteArrayZeroReadCases(BufferIterator iterator) { 476 // Zero length reads do nothing. 477 int posBeforeRead = iterator.pos(); 478 byte[] dstWithExistingValues = new byte[] { 11, 22, 33, 44, 55, 66, 77, 88 }; 479 iterator.readByteArray(dstWithExistingValues, 0, 0); 480 assertEquals(posBeforeRead, iterator.pos()); 481 assertArrayEquals(new byte[] { 11, 22, 33, 44, 55, 66, 77, 88 }, dstWithExistingValues); 482 483 try { 484 iterator.readByteArray(null, 0, 0); 485 fail(); 486 } catch (NullPointerException expected) { 487 } 488 assertEquals(posBeforeRead, iterator.pos()); 489 490 byte[] dst = new byte[10]; 491 492 // Before bounds. 493 iterator.seek(-1); 494 assertReadByteArrayFails(iterator, dst, 0, 1); 495 496 // After bounds. 497 iterator.seek(12); 498 assertReadByteArrayFails(iterator, dst, 0, 1); 499 500 // dst too small. 501 assertReadByteArrayFails(iterator, dst, 0, 11); // dst can only hold 10 bytes 502 503 // offset leaves dst too small. 504 assertReadByteArrayFails(iterator, dst, 1, 10); 505 506 // Invalid offset 507 assertReadByteArrayFails(iterator, dst, -1, 2); 508 assertReadByteArrayFails(iterator, dst, 2, 2); 509 510 // Null dst 511 try { 512 iterator.readByteArray(null, 0, 1); 513 fail(); 514 } catch (NullPointerException expected) { 515 } 516 } 517 assertReadByteArrayFails( BufferIterator iterator, byte[] dst, int offset, int intCount)518 private static void assertReadByteArrayFails( 519 BufferIterator iterator, byte[] dst, int offset, int intCount) { 520 521 int posBefore = iterator.pos(); 522 try { 523 iterator.readByteArray(dst, offset, intCount); 524 fail(); 525 } catch (IndexOutOfBoundsException expected) { 526 } 527 assertEquals(posBefore, iterator.pos()); 528 } 529 assertReadByteArraySucceeds( BufferIterator iterator, byte[] underlyingData, int byteCount)530 private static void assertReadByteArraySucceeds( 531 BufferIterator iterator, byte[] underlyingData, int byteCount) { 532 533 int posBefore = iterator.pos(); 534 535 // Create a byte[] containing book-end bytes we don't expect to be touched: 536 // [Byte.MAX_VALUE, {the bytes we expect from underlyingData from posBefore onward}, 537 // Byte.MIN_VALUE]. 538 byte[] expectedBytes = new byte[byteCount + 2]; 539 expectedBytes[0] = Byte.MAX_VALUE; 540 expectedBytes[byteCount - 1] = Byte.MIN_VALUE; 541 System.arraycopy(underlyingData, posBefore, expectedBytes, 1, byteCount); 542 543 // Get the true data. 544 byte[] dst = new byte[byteCount + 2]; 545 // Copy the two bytes we expect to be untouched. 546 dst[0] = expectedBytes[0]; 547 dst[byteCount - 1] = expectedBytes[byteCount - 1]; 548 // Do the read. 549 iterator.readByteArray(dst, 1, byteCount); 550 551 assertArrayEquals(expectedBytes, dst); 552 assertEquals(posBefore + byteCount, iterator.pos()); 553 } 554 assertReadIntArrayFails( BufferIterator iterator, int[] dst, int offset, int intCount)555 private static void assertReadIntArrayFails( 556 BufferIterator iterator, int[] dst, int offset, int intCount) { 557 558 int posBefore = iterator.pos(); 559 try { 560 iterator.readIntArray(dst, offset, intCount); 561 fail(); 562 } catch (IndexOutOfBoundsException expected) { 563 } 564 assertEquals(posBefore, iterator.pos()); 565 } 566 assertReadIntArraySucceeds( BufferIterator iterator, byte[] underlyingData, ByteOrder byteOrder, int intCount)567 private static void assertReadIntArraySucceeds( 568 BufferIterator iterator, byte[] underlyingData, ByteOrder byteOrder, int intCount) { 569 570 int posBefore = iterator.pos(); 571 572 // Create an int[] containing book-end ints we don't expect to be touched: 573 // [Integer.MAX_VALUE, {the ints we expect from underlyingData from posBefore onward}, 574 // Integer.MIN_VALUE]. 575 576 // Create an IntBuffer containing the ints we'd expect from underlyingData from posBefore 577 // onward. 578 ByteBuffer byteBuffer = ByteBuffer.wrap(underlyingData); 579 byteBuffer.position(posBefore); 580 IntBuffer expectedIntsBuffer = byteBuffer.slice().order(byteOrder).asIntBuffer(); 581 assertEquals(byteOrder, expectedIntsBuffer.order()); 582 583 // Copy the ints we expect. 584 int[] expectedInts = new int[intCount + 2]; 585 expectedInts[0] = Integer.MAX_VALUE; 586 expectedInts[intCount - 1] = Integer.MIN_VALUE; 587 expectedIntsBuffer.get(expectedInts, 1, intCount); 588 589 // Get the true data. 590 int[] dst = new int[intCount + 2]; 591 dst[0] = expectedInts[0]; 592 dst[intCount - 1] = expectedInts[intCount - 1]; 593 iterator.readIntArray(dst, 1, intCount); 594 595 assertArrayEquals(expectedInts, dst); 596 assertEquals(posBefore + (intCount * Integer.BYTES), iterator.pos()); 597 } 598 assertReadIntFails(BufferIterator iterator)599 private static void assertReadIntFails(BufferIterator iterator) { 600 int posBefore = iterator.pos(); 601 try { 602 iterator.readInt(); 603 fail(); 604 } catch (IndexOutOfBoundsException expected) { 605 } 606 assertEquals(posBefore, iterator.pos()); 607 } 608 assertReadIntSucceeds(BufferIterator iterator, int expectedValue)609 private static void assertReadIntSucceeds(BufferIterator iterator, int expectedValue) { 610 int posBefore = iterator.pos(); 611 assertEquals(expectedValue, iterator.readInt()); 612 assertEquals(posBefore + Integer.BYTES, iterator.pos()); 613 } 614 assertReadShortFails(BufferIterator iterator)615 private static void assertReadShortFails(BufferIterator iterator) { 616 int posBefore = iterator.pos(); 617 try { 618 iterator.readShort(); 619 fail(); 620 } catch (IndexOutOfBoundsException expected) { 621 } 622 assertEquals(posBefore, iterator.pos()); 623 } 624 assertReadShortSucceeds(BufferIterator iterator, short expectedValue)625 private static void assertReadShortSucceeds(BufferIterator iterator, short expectedValue) { 626 int posBefore = iterator.pos(); 627 assertEquals(expectedValue, iterator.readShort()); 628 assertEquals(posBefore + Short.BYTES, iterator.pos()); 629 } 630 assertReadByteFails(BufferIterator iterator)631 private static void assertReadByteFails(BufferIterator iterator) { 632 int posBefore = iterator.pos(); 633 try { 634 iterator.readByte(); 635 fail(); 636 } catch (IndexOutOfBoundsException expected) { 637 } 638 // Must not advance pos. 639 assertEquals(posBefore, iterator.pos()); 640 } 641 assertReadByteSucceeds(BufferIterator iterator, byte expectedValue)642 private static void assertReadByteSucceeds(BufferIterator iterator, byte expectedValue) { 643 int posBefore = iterator.pos(); 644 assertEquals(expectedValue, iterator.readByte()); 645 assertEquals(posBefore + 1, iterator.pos()); 646 } 647 assertArrayEquals(int[] expected, int[] actual)648 private static void assertArrayEquals(int[] expected, int[] actual) { 649 assertEquals(Arrays.toString(expected), Arrays.toString(actual)); 650 } 651 assertArrayEquals(byte[] expected, byte[] actual)652 private static void assertArrayEquals(byte[] expected, byte[] actual) { 653 assertEquals(Arrays.toString(expected), Arrays.toString(actual)); 654 } 655 createBytes(int byteCount)656 private static byte[] createBytes(int byteCount) { 657 byte[] bytes = new byte[byteCount]; 658 for (int i = 0; i < byteCount; i++) { 659 bytes[i] = (byte) i; 660 } 661 return bytes; 662 } 663 createFile(byte[] bytes)664 private File createFile(byte[] bytes) throws Exception { 665 File file = File.createTempFile("bytes", null, tempDir); 666 try (FileOutputStream fos = new FileOutputStream(file)) { 667 fos.write(bytes); 668 } 669 return file; 670 } 671 } 672