|  | // Copyright 2015 The Bazel Authors. All rights reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  | package com.google.devtools.build.android.ziputils; | 
|  |  | 
|  | import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENHOW; | 
|  | import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENLEN; | 
|  | import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENOFF; | 
|  | import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENSIZ; | 
|  | import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDOFF; | 
|  | import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDSIG; | 
|  | import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDSIZ; | 
|  | import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDSUB; | 
|  | import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDTOT; | 
|  | import static java.nio.charset.StandardCharsets.UTF_8; | 
|  | import static org.junit.Assert.assertEquals; | 
|  | import static org.junit.Assert.assertNotNull; | 
|  | import static org.junit.Assert.assertNull; | 
|  | import static org.junit.Assert.assertSame; | 
|  | import static org.junit.Assert.fail; | 
|  |  | 
|  | import com.google.devtools.build.android.ziputils.ZipIn.ZipEntry; | 
|  | import java.io.IOException; | 
|  | import java.nio.ByteBuffer; | 
|  | import java.util.Arrays; | 
|  | import java.util.List; | 
|  | import java.util.zip.ZipInputStream; | 
|  | import org.junit.Before; | 
|  | import org.junit.Test; | 
|  | import org.junit.runner.RunWith; | 
|  | import org.junit.runners.JUnit4; | 
|  |  | 
|  | /** | 
|  | * Unit tests for {@link ZipIn}. | 
|  | */ | 
|  | @RunWith(JUnit4.class) | 
|  | public class ZipInTest { | 
|  |  | 
|  | private static final int ENTRY_COUNT = 1000; | 
|  | private FakeFileSystem fileSystem; | 
|  |  | 
|  | @Before | 
|  | public void setUp() throws Exception { | 
|  | fileSystem = new FakeFileSystem(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of endOfCentralDirectory method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testEndOfCentralDirectory() throws Exception { | 
|  |  | 
|  | String filename = "test.zip"; | 
|  | byte[] bytes; | 
|  | ByteBuffer buffer; | 
|  | String comment; | 
|  | int commentLen; | 
|  | int offset; | 
|  | ZipIn zipIn; | 
|  | EndOfCentralDirectory result; | 
|  | String subcase; | 
|  |  | 
|  | // Find it, even if it's the only useful thing in the file. | 
|  | subcase = " EOCD found it, "; | 
|  | bytes = new byte[] { | 
|  | 0x50, 0x4b, 0x05, 0x06, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | }; | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | result = zipIn.endOfCentralDirectory(); | 
|  | assertNotNull(subcase + "found", result); | 
|  |  | 
|  | subcase = " EOCD not there at all, "; | 
|  | bytes = new byte[]{ | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | }; | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | try { | 
|  | zipIn.endOfCentralDirectory(); | 
|  | fail(subcase + "expected IllegalStateException"); | 
|  | } catch (Exception ex) { | 
|  | assertSame(subcase + "caught exception", IllegalStateException.class, ex.getClass()); | 
|  | } | 
|  |  | 
|  | // If we can't read it, it's not there | 
|  | subcase = " EOCD too late to read, "; | 
|  | bytes = new byte[] { | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0x50, 0x4b, 0x05, 0x06, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | }; | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | try { | 
|  | zipIn.endOfCentralDirectory(); | 
|  | fail(subcase + "expected IndexOutOfBoundsException"); | 
|  | } catch (Exception ex) { | 
|  | assertSame(subcase + "caught exception", IndexOutOfBoundsException.class, ex.getClass()); | 
|  | } | 
|  |  | 
|  | // Current implementation doesn't know to scan past a bad EOCD record. | 
|  | // I'm not sure if it should. | 
|  | subcase = " EOCD good hidden by bad, "; | 
|  | bytes = new byte[] { | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0x50, 0x4b, 0x05, 0x06, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | 0x50, 0x4b, 0x05, 0x06, 0, 0, 0, 0, 0, 0, | 
|  | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
|  | }; | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | try { | 
|  | zipIn.endOfCentralDirectory(); | 
|  | fail(subcase + "expected IndexOutOfBoundsException"); | 
|  | } catch (Exception ex) { | 
|  | assertSame(subcase + "caught exception", IndexOutOfBoundsException.class, ex.getClass()); | 
|  | } | 
|  |  | 
|  | // Minimal format checking here, assuming the EndOfDirectoryTest class | 
|  | // test for that. | 
|  |  | 
|  | subcase = " EOCD truncated comment, "; | 
|  | bytes = new byte[100]; | 
|  | buffer = ByteBuffer.wrap(bytes); | 
|  | comment = "optional file comment"; | 
|  | commentLen = comment.getBytes(UTF_8).length; | 
|  | offset = bytes.length - ZipInputStream.ENDHDR - commentLen; | 
|  | buffer.position(offset); | 
|  | EndOfCentralDirectory.view(buffer, comment); | 
|  | byte[] truncated = Arrays.copyOf(bytes, bytes.length - 5); | 
|  | fileSystem.addFile(filename, truncated); | 
|  | zipIn = newZipIn(filename); | 
|  | try { // not sure this is the exception we want! | 
|  | zipIn.endOfCentralDirectory(); | 
|  | fail(subcase + "expected IllegalArgumentException"); | 
|  | } catch (Exception ex) { | 
|  | assertSame(subcase + "caught exception", IllegalArgumentException.class, ex.getClass()); | 
|  | } | 
|  |  | 
|  | subcase = " EOCD no comment, "; | 
|  | bytes = new byte[100]; | 
|  | buffer = ByteBuffer.wrap(bytes); | 
|  | comment = null; | 
|  | commentLen = 0; | 
|  | offset = bytes.length - ZipInputStream.ENDHDR - commentLen; | 
|  | buffer.position(offset); | 
|  | EndOfCentralDirectory.view(buffer, comment); | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | result = zipIn.endOfCentralDirectory(); | 
|  | assertNotNull(subcase + "found", result); | 
|  | assertEquals(subcase + "comment", "", result.getComment()); | 
|  | assertEquals(subcase + "marker", ZipInputStream.ENDSIG, (int) result.get(ENDSIG)); | 
|  |  | 
|  | subcase = " EOCD comment, "; | 
|  | bytes = new byte[100]; | 
|  | buffer = ByteBuffer.wrap(bytes); | 
|  | comment = "optional file comment"; | 
|  | commentLen = comment.getBytes(UTF_8).length; | 
|  | offset = bytes.length - ZipInputStream.ENDHDR - commentLen; | 
|  | buffer.position(offset); | 
|  | EndOfCentralDirectory.view(buffer, comment); | 
|  | assertEquals(subcase + "setup", comment, | 
|  | new String(bytes, bytes.length - commentLen, commentLen, UTF_8)); | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | result = zipIn.endOfCentralDirectory(); | 
|  | assertNotNull(subcase + "found", result); | 
|  | assertEquals(subcase + "comment", comment, result.getComment()); | 
|  | assertEquals(subcase + "marker", ZipInputStream.ENDSIG, (int) result.get(ENDSIG)); | 
|  |  | 
|  | subcase = " EOCD extra data, "; | 
|  | bytes = new byte[100]; | 
|  | buffer = ByteBuffer.wrap(bytes); | 
|  | comment = null; | 
|  | commentLen = 0; | 
|  | offset = bytes.length - ZipInputStream.ENDHDR - commentLen - 10; | 
|  | buffer.position(offset); | 
|  | EndOfCentralDirectory.view(buffer, comment); | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | result = zipIn.endOfCentralDirectory(); | 
|  | assertNotNull(subcase + "found", result); | 
|  | assertEquals(subcase + "comment", "", result.getComment()); | 
|  | assertEquals(subcase + "marker", ZipInputStream.ENDSIG, (int) result.get(ENDSIG)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of centralDirectory method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testCentralDirectory() throws Exception { | 
|  | String filename = "test.zip"; | 
|  | ByteBuffer buffer; | 
|  | int offset; | 
|  | ZipIn zipIn; | 
|  | String subcase; | 
|  | subcase = " EOCD extra data, "; | 
|  | String commonName = "thisIsNotNormal.txt"; | 
|  | int filenameLen = commonName.getBytes(UTF_8).length; | 
|  | int count = ENTRY_COUNT; | 
|  | int dirEntry = ZipInputStream.CENHDR; | 
|  | int before = count; | 
|  | int between = 0; // implementation doesn't tolerate data between dir entries, does the spec? | 
|  | int after = 20; | 
|  | int eocd = ZipInputStream.ENDHDR; | 
|  | int total = before + (count * (dirEntry + filenameLen)) + ((count - 1) * between) | 
|  | + after + eocd; | 
|  | byte[] bytes = new byte[total]; | 
|  | offset = before; | 
|  | for (int i = 0; i < count; i++) { | 
|  | if (i > 0) { | 
|  | offset += between; | 
|  | } | 
|  | buffer = ByteBuffer.wrap(bytes, offset, bytes.length - offset); | 
|  | DirectoryEntry.view(buffer, commonName, null, null) | 
|  | .set(CENHOW, (short) 8) | 
|  | .set(CENSIZ, before) | 
|  | .set(CENLEN, 2 * before) | 
|  | .set(CENOFF, i); // Not valid of course, but we're only testing central dir parsing. | 
|  | // and there are currently no checks in the parser to see if offset makes sense. | 
|  | offset += dirEntry + filenameLen; | 
|  | } | 
|  | offset += after; | 
|  | buffer = ByteBuffer.wrap(bytes, offset, bytes.length - offset); | 
|  | EndOfCentralDirectory.view(buffer, null) | 
|  | .set(ENDOFF, before) | 
|  | .set(ENDSIZ, offset - before - after) | 
|  | .set(ENDTOT, (short) count) | 
|  | .set(ENDSUB, (short) count); | 
|  |  | 
|  | fileSystem.addFile(filename, bytes); | 
|  | zipIn = newZipIn(filename); | 
|  | CentralDirectory result = zipIn.centralDirectory(); | 
|  | assertNotNull(subcase + "found", result); | 
|  | List<DirectoryEntry> list = result.list(); | 
|  | assertEquals(subcase + "size", count, list.size()); | 
|  | for (int i = 0; i < list.size(); i++) { | 
|  | assertEquals(subcase + "offset check[" + i + "]", i, list.get(i).get(CENOFF)); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of scanEntries method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testScanEntries() throws Exception { | 
|  | int count = ENTRY_COUNT * 100; | 
|  | String filename = "test.jar"; | 
|  |  | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  |  | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.scanEntries(new EntryHandler() { | 
|  | int count = 0; | 
|  | @Override | 
|  | public void handle(ZipIn in, LocalFileHeader header, DirectoryEntry dirEntry, | 
|  | ByteBuffer data) throws IOException { | 
|  | assertSame(zipIn, in); | 
|  | String filename = "pkg/f" + count + ".class"; | 
|  | assertEquals(filename, header.getFilename()); | 
|  | assertEquals(filename, dirEntry.getFilename()); | 
|  | count++; | 
|  | } | 
|  | }); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of nextHeaderFrom method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testNextHeaderFrom_long() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.endOfCentralDirectory(); | 
|  | count = 0; | 
|  | int offset = 0; | 
|  | LocalFileHeader header; | 
|  | do { | 
|  | header = zipIn.nextHeaderFrom(offset); | 
|  | String name = "pkg/f" + count + ".class"; | 
|  | if (header != null) { | 
|  | assertEquals(name, header.getFilename()); | 
|  | count++; | 
|  | offset = (int) header.fileOffset() + 4; | 
|  | } | 
|  | } while(header != null); | 
|  | assertEquals(ENTRY_COUNT, count); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of nextHeaderFrom method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testNextHeaderFrom_DirectoryEntry() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.centralDirectory(); | 
|  | List<DirectoryEntry> list = zipIn.centralDirectory().list(); | 
|  | count = 0; | 
|  | String name; | 
|  | LocalFileHeader header = zipIn.nextHeaderFrom(null); | 
|  | for (DirectoryEntry dirEntry : list) { | 
|  | name = "pkg/f" + count + ".class"; | 
|  | assertEquals(name, dirEntry.getFilename()); | 
|  | assertEquals(name, header.getFilename()); | 
|  | header = zipIn.nextHeaderFrom(dirEntry); | 
|  | count++; | 
|  | } | 
|  | assertNull(header); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of localHeaderFor method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testLocalHeaderFor() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.centralDirectory(); | 
|  | List<DirectoryEntry> list = zipIn.centralDirectory().list(); | 
|  | count = 0; | 
|  | String name; | 
|  | LocalFileHeader header; | 
|  | for (DirectoryEntry dirEntry : list) { | 
|  | name = "pkg/f" + count + ".class"; | 
|  | header = zipIn.localHeaderFor(dirEntry); | 
|  | assertEquals(name, dirEntry.getFilename()); | 
|  | assertEquals(name, header.getFilename()); | 
|  | count++; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of localHeaderAt method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testLocalHeaderAt() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.centralDirectory(); | 
|  | List<DirectoryEntry> list = zipIn.centralDirectory().list(); | 
|  | count = 0; | 
|  | String name; | 
|  | LocalFileHeader header; | 
|  | for (DirectoryEntry dirEntry : list) { | 
|  | name = "pkg/f" + count + ".class"; | 
|  | header = zipIn.localHeaderAt(dirEntry.get(CENOFF)); | 
|  | assertEquals(name, dirEntry.getFilename()); | 
|  | assertEquals(name, header.getFilename()); | 
|  | count++; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of nextFrom method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testNextFrom_long() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.centralDirectory(); | 
|  | count = 0; | 
|  | int offset = 0; | 
|  | ZipEntry zipEntry; | 
|  | do { | 
|  | zipEntry = zipIn.nextFrom(offset); | 
|  | String name = "pkg/f" + count + ".class"; | 
|  | if (zipEntry.getCode() != ZipEntry.Status.ENTRY_NOT_FOUND) { | 
|  | assertNotNull(zipEntry.getHeader()); | 
|  | assertNotNull(zipEntry.getDirEntry()); | 
|  | assertEquals(name, zipEntry.getHeader().getFilename()); | 
|  | assertEquals(name, zipEntry.getDirEntry().getFilename()); | 
|  | count++; | 
|  | offset = (int) zipEntry.getHeader().fileOffset() + 4; | 
|  | } | 
|  | } while(zipEntry.getCode() != ZipEntry.Status.ENTRY_NOT_FOUND); | 
|  | assertEquals(ENTRY_COUNT, count); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of nextFrom method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testNextFrom_DirectoryEntry() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.centralDirectory(); | 
|  | List<DirectoryEntry> list = zipIn.centralDirectory().list(); | 
|  | count = 0; | 
|  | String name; | 
|  | ZipEntry zipEntry = zipIn.nextFrom(null); | 
|  | for (DirectoryEntry dirEntry : list) { | 
|  | if (zipEntry.getCode() == ZipEntry.Status.ENTRY_NOT_FOUND) { | 
|  | break; | 
|  | } | 
|  | name = "pkg/f" + count + ".class"; | 
|  | assertNotNull(zipEntry.getHeader()); | 
|  | assertNotNull(zipEntry.getDirEntry()); | 
|  | assertEquals(name, zipEntry.getHeader().getFilename()); | 
|  | assertEquals(name, zipEntry.getDirEntry().getFilename()); | 
|  | zipEntry = zipIn.nextFrom(dirEntry); | 
|  | count++; | 
|  | } | 
|  | assertEquals(ENTRY_COUNT, count); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of entryAt method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testEntryAt() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.centralDirectory(); | 
|  | List<DirectoryEntry> list = zipIn.centralDirectory().list(); | 
|  | count = 0; | 
|  | String name; | 
|  | ZipEntry zipEntry; | 
|  | for (DirectoryEntry dirEntry : list) { | 
|  | zipEntry = zipIn.entryAt(dirEntry.get(CENOFF)); | 
|  | name = "pkg/f" + count + ".class"; | 
|  | assertNotNull(zipEntry.getHeader()); | 
|  | assertNotNull(zipEntry.getDirEntry()); | 
|  | assertEquals(name, zipEntry.getHeader().getFilename()); | 
|  | assertEquals(name, zipEntry.getDirEntry().getFilename()); | 
|  | count++; | 
|  | } | 
|  | assertEquals(ENTRY_COUNT, count); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test of entryWith method, of class ZipIn. | 
|  | */ | 
|  | @Test | 
|  | public void testEntryWith() throws Exception { | 
|  | int count = ENTRY_COUNT; | 
|  | String filename = "test.jar"; | 
|  | ZipFileBuilder builder = new ZipFileBuilder(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | builder.add("pkg/f" + i + ".class", "All day long"); | 
|  | } | 
|  | builder.create(filename); | 
|  | final ZipIn zipIn = newZipIn(filename); | 
|  | zipIn.centralDirectory(); | 
|  | count = 0; | 
|  | int offset = 0; | 
|  | LocalFileHeader header; | 
|  | do { | 
|  | header = zipIn.nextHeaderFrom(offset); | 
|  | String name = "pkg/f" + count + ".class"; | 
|  | if (header != null) { | 
|  | ZipEntry zipEntry = zipIn.entryWith(header); | 
|  | assertNotNull(zipEntry.getDirEntry()); | 
|  | assertSame(header, zipEntry.getHeader()); | 
|  | assertEquals(name, zipEntry.getHeader().getFilename()); | 
|  | assertEquals(name, zipEntry.getDirEntry().getFilename()); | 
|  | assertEquals(name, header.getFilename()); | 
|  | count++; | 
|  | offset = (int) header.fileOffset() + 4; | 
|  | } | 
|  | } while(header != null); | 
|  | assertEquals(ENTRY_COUNT, count); | 
|  | } | 
|  |  | 
|  | private ZipIn newZipIn(String filename) throws IOException { | 
|  | return new ZipIn(fileSystem.getInputChannel(filename), filename); | 
|  | } | 
|  | } |