IndexLoaderV1 { IndexV1 loadIndex(ReaderAtEnd reader) throws InvalidIndexException, IOException { Buffer meta = reader.readAtEnd(IndexV1.FOOTER_SIZE, IndexV1.FOOTER_SIZE); int crc32 = meta.getInt(); int count = meta.getInt(); int bytes = meta.getInt(); int magic = meta.getInt(); if (magic != MAGIC) { throw new InvalidIndexException("Magic number mismatch"); } if (count < 1) { throw new InvalidIndexException("Invalid entry count"); } if (bytes < count * IndexEntryV1.SIZE + IndexV1.FOOTER_SIZE) { throw new InvalidIndexException("Invalid size"); } if (bytes % blockSize != 0) { throw new InvalidIndexException("Invalid size alignment"); } Buffer entries = reader.readAtEnd(IndexV1.FOOTER_SIZE + count * IndexEntryV1.SIZE, count * IndexEntryV1.SIZE); CRC32 checksum = new CRC32(); entries.mark(); entries.update(checksum); entries.reset(); if (crc32 != (int) checksum.getValue()) { throw new InvalidIndexException("Invalid checksum"); } long lastMsb = Long.MIN_VALUE; long lastLsb = Long.MIN_VALUE; byte[] entry = new byte[IndexEntryV1.SIZE]; entries.mark(); for (int i = 0; i < count; i++) { entries.get(entry); Buffer buffer = wrap(entry); long msb = buffer.getLong(); long lsb = buffer.getLong(); int offset = buffer.getInt(); int size = buffer.getInt(); if (lastMsb > msb || (lastMsb == msb && lastLsb > lsb)) { throw new InvalidIndexException("Incorrect entry ordering"); } if (lastMsb == msb && lastLsb == lsb && i > 0) { throw new InvalidIndexException("Duplicate entry"); } if (offset < 0) { throw new InvalidIndexException("Invalid entry offset"); } if (offset % blockSize != 0) { throw new InvalidIndexException("Invalid entry offset alignment"); } if (size < 1) { throw new InvalidIndexException("Invalid entry size"); } lastMsb = msb; lastLsb = lsb; } entries.reset(); return new IndexV1(entries); } IndexLoaderV1(int blockSize);   }
@Test(expected = InvalidIndexException.class) public void testInvalidMagic() throws Exception { Buffer buffer = Buffer.allocate(IndexV1.FOOTER_SIZE); try { loadIndex(buffer); } catch (InvalidIndexException e) { assertEquals("Magic number mismatch", e.getMessage()); throw e; } }
@Test public void testLoadIndex() throws Exception { Buffer entries = Buffer.allocate(2 * IndexEntryV1.SIZE); entries.duplicate() .putLong(0).putLong(0).putInt(0).putInt(1).putInt(0) .putLong(0).putLong(1).putInt(1).putInt(1).putInt(0); Buffer buffer = Buffer.allocate(2 * IndexEntryV1.SIZE + IndexV1.FOOTER_SIZE); buffer.duplicate() .put(entries.duplicate()) .putInt(checksum(entries)) .putInt(2) .putInt(2 * IndexEntryV1.SIZE + IndexV1.FOOTER_SIZE) .putInt(IndexLoaderV1.MAGIC); assertNotNull(loadIndex(buffer)); }