MinimalZipParser { public static MinimalZipEntry parseCentralDirectoryEntry(InputStream in) throws IOException { if (((int) read32BitUnsigned(in)) != CENTRAL_DIRECTORY_ENTRY_SIGNATURE) { throw new ZipException("Bad central directory header"); } skipOrDie(in, 2 + 2); int generalPurposeFlags = read16BitUnsigned(in); int compressionMethod = read16BitUnsigned(in); skipOrDie(in, 2 + 2); long crc32OfUncompressedData = read32BitUnsigned(in); long compressedSize = read32BitUnsigned(in); long uncompressedSize = read32BitUnsigned(in); int fileNameLength = read16BitUnsigned(in); int extrasLength = read16BitUnsigned(in); int commentLength = read16BitUnsigned(in); skipOrDie(in, 2 + 2 + 4); long fileOffsetOfLocalEntry = read32BitUnsigned(in); byte[] fileNameBuffer = new byte[fileNameLength]; readOrDie(in, fileNameBuffer, 0, fileNameBuffer.length); skipOrDie(in, extrasLength + commentLength); boolean generalPurposeFlagBit11 = (generalPurposeFlags & (0x1 << 10)) != 0; return new MinimalZipEntry( compressionMethod, crc32OfUncompressedData, compressedSize, uncompressedSize, fileNameBuffer, generalPurposeFlagBit11, fileOffsetOfLocalEntry); }  static MinimalZipEntry parseCentralDirectoryEntry(InputStream in); static long parseLocalEntryAndGetCompressedDataOffset(InputStream in); static long locateStartOfEocd(RandomAccessFileInputStream in, int searchBufferLength); static int locateStartOfEocd(byte[] buffer); static MinimalCentralDirectoryMetadata parseEocd(InputStream in); static final int EOCD_SIGNATURE; static final int CENTRAL_DIRECTORY_ENTRY_SIGNATURE; static final int LOCAL_ENTRY_SIGNATURE; }
@Test public void testParseCentralDirectoryEntry() throws Exception { ByteArrayInputStream in = new ByteArrayInputStream(unitTestZipArchive); in.mark(unitTestZipArchive.length); int eocdOffset = MinimalZipParser.locateStartOfEocd(unitTestZipArchive); Assert.assertEquals(eocdOffset, in.skip(eocdOffset)); MinimalCentralDirectoryMetadata metadata = MinimalZipParser.parseEocd(in); in.reset(); Assert.assertEquals( metadata.getOffsetOfCentralDirectory(), in.skip(metadata.getOffsetOfCentralDirectory())); for (UnitTestZipEntry expectedEntry : UnitTestZipArchive.allEntriesInFileOrder) { MinimalZipEntry parsed = MinimalZipParser.parseCentralDirectoryEntry(in); Assert.assertEquals(expectedEntry.path, parsed.getFileName()); byte[] expectedSignatureBlock = new byte[] {0x50, 0x4b, 0x03, 0x04}; for (int index = 0; index < 4; index++) { byte actualByte = unitTestZipArchive[((int) parsed.getFileOffsetOfLocalEntry()) + index]; Assert.assertEquals(expectedSignatureBlock[index], actualByte); } if (expectedEntry.level > 0) { Assert.assertEquals(8 , parsed.getCompressionMethod()); } else { Assert.assertEquals(0 , parsed.getCompressionMethod()); } byte[] uncompressedContent = expectedEntry.getUncompressedBinaryContent(); Assert.assertEquals(uncompressedContent.length, parsed.getUncompressedSize()); CRC32 crc32 = new CRC32(); crc32.update(uncompressedContent); Assert.assertEquals(crc32.getValue(), parsed.getCrc32OfUncompressedData()); byte[] compressedContent = expectedEntry.getCompressedBinaryContent(); Assert.assertEquals(compressedContent.length, parsed.getCompressedSize()); } }