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