Browse Source

Finish implementation of ZipFile, use it in Expand (AKA <unzip>).

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274743 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 22 years ago
parent
commit
ad9c15103d
3 changed files with 98 additions and 45 deletions
  1. +11
    -41
      src/main/org/apache/tools/ant/taskdefs/Expand.java
  2. +86
    -1
      src/main/org/apache/tools/zip/ZipFile.java
  3. +1
    -3
      src/testcases/org/apache/tools/ant/taskdefs/UnzipTest.java

+ 11
- 41
src/main/org/apache/tools/ant/taskdefs/Expand.java View File

@@ -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) {}
}
}


+ 86
- 1
src/main/org/apache/tools/zip/ZipFile.java View File

@@ -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;
}
}

}

+ 1
- 3
src/testcases/org/apache/tools/ant/taskdefs/UnzipTest.java View File

@@ -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");
}




Loading…
Cancel
Save