git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274743 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -56,16 +56,13 @@ package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.RandomAccessFile; | |||
| import java.io.FileOutputStream; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.InputStream; | |||
| import java.io.IOException; | |||
| import java.util.Arrays; | |||
| import java.util.Date; | |||
| import java.util.Enumeration; | |||
| import java.util.Vector; | |||
| import java.util.zip.ZipInputStream; | |||
| import java.util.zip.ZipEntry; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.DirectoryScanner; | |||
| import org.apache.tools.ant.Project; | |||
| @@ -74,6 +71,8 @@ import org.apache.tools.ant.types.FileSet; | |||
| import org.apache.tools.ant.types.PatternSet; | |||
| import org.apache.tools.ant.types.selectors.SelectorUtils; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.tools.zip.ZipEntry; | |||
| import org.apache.tools.zip.ZipFile; | |||
| /** | |||
| * Unzip a file. | |||
| @@ -154,37 +153,13 @@ public class Expand extends Task { | |||
| */ | |||
| protected void expandFile(FileUtils fileUtils, File srcF, File dir) { | |||
| log("Expanding: " + srcF + " into " + dir, Project.MSG_INFO); | |||
| ZipInputStream zis = null; | |||
| FileInputStream fis = null; | |||
| RandomAccessFile raf = null; | |||
| byte[] buff = new byte[MARKER_SIZE]; | |||
| ZipFile zf = null; | |||
| try { | |||
| raf = new RandomAccessFile(srcF, "r"); | |||
| long offset = 0; | |||
| int more = raf.read(buff); | |||
| boolean foundMarker = false; | |||
| while (more != -1 || offset < MAX_LOOKAHEAD) { | |||
| if (Arrays.equals(buff, ZIPMARKER)) { | |||
| foundMarker = true; | |||
| break; | |||
| } | |||
| raf.seek(++offset); | |||
| more = raf.read(buff); | |||
| } | |||
| raf.close(); | |||
| raf = null; | |||
| fis = new FileInputStream(srcF); | |||
| if (foundMarker && offset > 0) { | |||
| log("found a preamble of " + offset | |||
| + " bytes, probably a self-extracting archive"); | |||
| fis.skip(offset); | |||
| } | |||
| zis = new ZipInputStream(fis); | |||
| ZipEntry ze = null; | |||
| while ((ze = zis.getNextEntry()) != null) { | |||
| extractFile(fileUtils, srcF, dir, zis, | |||
| zf = new ZipFile(srcF, "UTF8"); | |||
| Enumeration enum = zf.getEntries(); | |||
| while (enum.hasMoreElements()) { | |||
| ZipEntry ze = (ZipEntry) enum.nextElement(); | |||
| extractFile(fileUtils, srcF, dir, zf.getInputStream(ze), | |||
| ze.getName(), new Date(ze.getTime()), | |||
| ze.isDirectory()); | |||
| } | |||
| @@ -194,14 +169,9 @@ public class Expand extends Task { | |||
| throw new BuildException("Error while expanding " + srcF.getPath(), | |||
| ioe); | |||
| } finally { | |||
| if (raf != null) { | |||
| try { | |||
| raf.close(); | |||
| } catch (IOException e) {} | |||
| } | |||
| if (zis != null) { | |||
| if (zf != null) { | |||
| try { | |||
| zis.close(); | |||
| zf.close(); | |||
| } catch (IOException e) {} | |||
| } | |||
| } | |||
| @@ -63,6 +63,8 @@ import java.util.Calendar; | |||
| import java.util.Date; | |||
| import java.util.Enumeration; | |||
| import java.util.Hashtable; | |||
| import java.util.zip.Inflater; | |||
| import java.util.zip.InflaterInputStream; | |||
| import java.util.zip.ZipException; | |||
| /** | |||
| @@ -202,7 +204,22 @@ public class ZipFile { | |||
| */ | |||
| public InputStream getInputStream(ZipEntry ze) | |||
| throws IOException, ZipException { | |||
| return null; | |||
| Long start = (Long) dataOffsets.get(ze); | |||
| if (start == null) { | |||
| return null; | |||
| } | |||
| BoundedInputStream bis = | |||
| new BoundedInputStream(start.longValue(), ze.getCompressedSize()); | |||
| switch (ze.getMethod()) { | |||
| case ZipEntry.STORED: | |||
| return bis; | |||
| case ZipEntry.DEFLATED: | |||
| bis.addDummy(); | |||
| return new InflaterInputStream(bis, new Inflater(true)); | |||
| default: | |||
| throw new ZipException("Found unsupported compression method " | |||
| + ze.getMethod()); | |||
| } | |||
| } | |||
| private static final int CFH_LEN = | |||
| @@ -414,4 +431,72 @@ public class ZipFile { | |||
| } | |||
| } | |||
| /** | |||
| * InputStream that delegates requests to the underlying | |||
| * RandomAccessFile, making sure that only bytes from a certain | |||
| * range can be read. | |||
| */ | |||
| private class BoundedInputStream extends InputStream { | |||
| private long start, remaining; | |||
| private long loc; | |||
| private boolean addDummyByte = false; | |||
| BoundedInputStream(long start, long remaining) { | |||
| this.start = start; | |||
| this.remaining = remaining; | |||
| loc = start; | |||
| } | |||
| public int read() throws IOException { | |||
| if (remaining-- <= 0) { | |||
| if (addDummyByte) { | |||
| addDummyByte = false; | |||
| return 0; | |||
| } | |||
| return -1; | |||
| } | |||
| synchronized (archive) { | |||
| archive.seek(loc++); | |||
| return archive.read(); | |||
| } | |||
| } | |||
| public int read(byte[] b, int off, int len) throws IOException { | |||
| if (remaining <= 0) { | |||
| if (addDummyByte) { | |||
| addDummyByte = false; | |||
| b[off] = 0; | |||
| return 1; | |||
| } | |||
| return -1; | |||
| } | |||
| if (len <= 0) { | |||
| return 0; | |||
| } | |||
| if (len > remaining) { | |||
| len = (int) remaining; | |||
| } | |||
| int ret = -1; | |||
| synchronized (archive) { | |||
| archive.seek(loc); | |||
| ret = archive.read(b, off, len); | |||
| } | |||
| if (ret > 0) { | |||
| loc += ret; | |||
| remaining -= ret; | |||
| } | |||
| return ret; | |||
| } | |||
| /** | |||
| * Inflater needs an extra dummy byte for nowrap - see | |||
| * Inflater's javadocs. | |||
| */ | |||
| void addDummy() { | |||
| addDummyByte = true; | |||
| } | |||
| } | |||
| } | |||
| @@ -138,9 +138,7 @@ public class UnzipTest extends BuildFileTest { | |||
| * PR 16213 | |||
| */ | |||
| public void testSelfExtractingArchive() { | |||
| expectLogContaining("selfExtractingArchive", | |||
| "found a preamble of 38439 bytes, " | |||
| + "probably a self-extracting archive"); | |||
| executeTarget("selfExtractingArchive"); | |||
| } | |||