diff -r 9839e9a75bcf -r 0d277415ed02 emul/mini/src/main/java/java/util/zip/ZipInputStream.java --- a/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Wed Jan 30 14:03:49 2013 +0100 +++ b/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Thu Feb 07 12:58:12 2013 +0100 @@ -27,10 +27,6 @@ import java.io.InputStream; import java.io.IOException; -import java.io.EOFException; -import java.io.PushbackInputStream; -import static java.util.zip.ZipConstants64.*; -import org.apidesign.bck2brwsr.core.JavaScriptBody; /** * This class implements an input stream filter for reading files in the @@ -41,28 +37,7 @@ */ public class ZipInputStream extends InflaterInputStream implements ZipConstants { - private ZipEntry entry; - private int flag; - private CRC32 crc = new CRC32(); - private long remaining; - private byte[] tmpbuf = new byte[512]; - - private static final int STORED = ZipEntry.STORED; - private static final int DEFLATED = ZipEntry.DEFLATED; - - private boolean closed = false; - // this flag is set to true after EOF has reached for - // one entry - private boolean entryEOF = false; - - /** - * Check to make sure that this stream has not been closed - */ - private void ensureOpen() throws IOException { - if (closed) { - throw new IOException("Stream closed"); - } - } + private final org.apidesign.bck2brwsr.emul.zip.ZipInputStream impl; /** * Creates a new ZIP input stream. @@ -73,12 +48,8 @@ * @param in the actual input stream */ public ZipInputStream(InputStream in) { -// this(in, "UTF-8"); - super(new PushbackInputStream(in, 512), new Inflater(true), 512); - usesDefaultInflater = true; - if(in == null) { - throw new NullPointerException("in is null"); - } + super(null); + impl = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(in); } /** @@ -115,20 +86,7 @@ * @exception IOException if an I/O error has occurred */ public ZipEntry getNextEntry() throws IOException { - ensureOpen(); - if (entry != null) { - closeEntry(); - } - crc.reset(); - inf.reset(); - if ((entry = readLOC()) == null) { - return null; - } - if (entry.method == STORED) { - remaining = entry.size; - } - entryEOF = false; - return entry; + return impl.getNextEntry(); } /** @@ -138,9 +96,7 @@ * @exception IOException if an I/O error has occurred */ public void closeEntry() throws IOException { - ensureOpen(); - while (read(tmpbuf, 0, tmpbuf.length) != -1) ; - entryEOF = true; + impl.closeEntry(); } /** @@ -155,12 +111,7 @@ * */ public int available() throws IOException { - ensureOpen(); - if (entryEOF) { - return 0; - } else { - return 1; - } + return impl.available(); } /** @@ -181,51 +132,7 @@ * @exception IOException if an I/O error has occurred */ public int read(byte[] b, int off, int len) throws IOException { - ensureOpen(); - if (off < 0 || len < 0 || off > b.length - len) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - - if (entry == null) { - return -1; - } - switch (entry.method) { - case DEFLATED: - len = super.read(b, off, len); - if (len == -1) { - readEnd(entry); - entryEOF = true; - entry = null; - } else { - crc.update(b, off, len); - } - return len; - case STORED: - if (remaining <= 0) { - entryEOF = true; - entry = null; - return -1; - } - if (len > remaining) { - len = (int)remaining; - } - len = in.read(b, off, len); - if (len == -1) { - throw new ZipException("unexpected EOF"); - } - crc.update(b, off, len); - remaining -= len; - if (remaining == 0 && entry.crc != crc.getValue()) { - throw new ZipException( - "invalid entry CRC (expected 0x" + Long.toHexString(entry.crc) + - " but got 0x" + Long.toHexString(crc.getValue()) + ")"); - } - return len; - default: - throw new ZipException("invalid compression method"); - } + return impl.read(b, off, len); } /** @@ -237,25 +144,7 @@ * @exception IllegalArgumentException if n < 0 */ public long skip(long n) throws IOException { - if (n < 0) { - throw new IllegalArgumentException("negative skip length"); - } - ensureOpen(); - int max = (int)Math.min(n, Integer.MAX_VALUE); - int total = 0; - while (total < max) { - int len = max - total; - if (len > tmpbuf.length) { - len = tmpbuf.length; - } - len = read(tmpbuf, 0, len); - if (len == -1) { - entryEOF = true; - break; - } - total += len; - } - return total; + return impl.skip(n); } /** @@ -264,89 +153,7 @@ * @exception IOException if an I/O error has occurred */ public void close() throws IOException { - if (!closed) { - super.close(); - closed = true; - } - } - - private byte[] b = new byte[256]; - - /* - * Reads local file (LOC) header for next entry. - */ - private ZipEntry readLOC() throws IOException { - try { - readFully(tmpbuf, 0, LOCHDR); - } catch (EOFException e) { - return null; - } - if (get32(tmpbuf, 0) != LOCSIG) { - return null; - } - // get flag first, we need check EFS. - flag = get16(tmpbuf, LOCFLG); - // get the entry name and create the ZipEntry first - int len = get16(tmpbuf, LOCNAM); - int blen = b.length; - if (len > blen) { - do - blen = blen * 2; - while (len > blen); - b = new byte[blen]; - } - readFully(b, 0, len); - // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8 - ZipEntry e = createZipEntry(((flag & EFS) != 0) - ? toStringUTF8(b, len) - : toString(b, len)); - // now get the remaining fields for the entry - if ((flag & 1) == 1) { - throw new ZipException("encrypted ZIP entry not supported"); - } - e.method = get16(tmpbuf, LOCHOW); - e.time = get32(tmpbuf, LOCTIM); - if ((flag & 8) == 8) { - /* "Data Descriptor" present */ - if (e.method != DEFLATED) { - throw new ZipException( - "only DEFLATED entries can have EXT descriptor"); - } - } else { - e.crc = get32(tmpbuf, LOCCRC); - e.csize = get32(tmpbuf, LOCSIZ); - e.size = get32(tmpbuf, LOCLEN); - } - len = get16(tmpbuf, LOCEXT); - if (len > 0) { - byte[] bb = new byte[len]; - readFully(bb, 0, len); - e.setExtra(bb); - // extra fields are in "HeaderID(2)DataSize(2)Data... format - if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) { - int off = 0; - while (off + 4 < len) { - int sz = get16(bb, off + 2); - if (get16(bb, off) == ZIP64_EXTID) { - off += 4; - // LOC extra zip64 entry MUST include BOTH original and - // compressed file size fields - if (sz < 16 || (off + sz) > len ) { - // Invalid zip64 extra fields, simply skip. Even it's - // rare, it's possible the entry size happens to be - // the magic value and it "accidnetly" has some bytes - // in extra match the id. - return e; - } - e.size = get64(bb, off); - e.csize = get64(bb, off + 8); - break; - } - off += (sz + 4); - } - } - } - return e; + impl.close(); } /** @@ -360,108 +167,28 @@ return new ZipEntry(name); } - /* - * Reads end of deflated entry as well as EXT descriptor if present. - */ - private void readEnd(ZipEntry e) throws IOException { - int n = inf.getRemaining(); - if (n > 0) { - ((PushbackInputStream)in).unread(buf, len - n, n); - } - if ((flag & 8) == 8) { - /* "Data Descriptor" present */ - if (inf.getBytesWritten() > ZIP64_MAGICVAL || - inf.getBytesRead() > ZIP64_MAGICVAL) { - // ZIP64 format - readFully(tmpbuf, 0, ZIP64_EXTHDR); - long sig = get32(tmpbuf, 0); - if (sig != EXTSIG) { // no EXTSIG present - e.crc = sig; - e.csize = get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC); - e.size = get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC); - ((PushbackInputStream)in).unread( - tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC); - } else { - e.crc = get32(tmpbuf, ZIP64_EXTCRC); - e.csize = get64(tmpbuf, ZIP64_EXTSIZ); - e.size = get64(tmpbuf, ZIP64_EXTLEN); - } - } else { - readFully(tmpbuf, 0, EXTHDR); - long sig = get32(tmpbuf, 0); - if (sig != EXTSIG) { // no EXTSIG present - e.crc = sig; - e.csize = get32(tmpbuf, EXTSIZ - EXTCRC); - e.size = get32(tmpbuf, EXTLEN - EXTCRC); - ((PushbackInputStream)in).unread( - tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC); - } else { - e.crc = get32(tmpbuf, EXTCRC); - e.csize = get32(tmpbuf, EXTSIZ); - e.size = get32(tmpbuf, EXTLEN); - } - } - } - if (e.size != inf.getBytesWritten()) { - throw new ZipException( - "invalid entry size (expected " + e.size + - " but got " + inf.getBytesWritten() + " bytes)"); - } - if (e.csize != inf.getBytesRead()) { - throw new ZipException( - "invalid entry compressed size (expected " + e.csize + - " but got " + inf.getBytesRead() + " bytes)"); - } - if (e.crc != crc.getValue()) { - throw new ZipException( - "invalid entry CRC (expected 0x" + Long.toHexString(e.crc) + - " but got 0x" + Long.toHexString(crc.getValue()) + ")"); - } + @Override + public int read() throws IOException { + return impl.read(); } - /* - * Reads bytes, blocking until all bytes are read. - */ - private void readFully(byte[] b, int off, int len) throws IOException { - while (len > 0) { - int n = in.read(b, off, len); - if (n == -1) { - throw new EOFException(); - } - off += n; - len -= n; - } + @Override + public boolean markSupported() { + return impl.markSupported(); } - /* - * Fetches unsigned 16-bit value from byte array at specified offset. - * The bytes are assumed to be in Intel (little-endian) byte order. - */ - private static final int get16(byte b[], int off) { - return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8); + @Override + public void mark(int readlimit) { + impl.mark(readlimit); } - /* - * Fetches unsigned 32-bit value from byte array at specified offset. - * The bytes are assumed to be in Intel (little-endian) byte order. - */ - private static final long get32(byte b[], int off) { - return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL; + @Override + public void reset() throws IOException { + impl.reset(); } - /* - * Fetches signed 64-bit value from byte array at specified offset. - * The bytes are assumed to be in Intel (little-endian) byte order. - */ - private static final long get64(byte b[], int off) { - return get32(b, off) | (get32(b, off+4) << 32); - } - - private static String toStringUTF8(byte[] arr, int len) { - return new String(arr, 0, len); - } - - private static String toString(byte[] b, int len) { - return new String(b, 0, len); + @Override + public int read(byte[] b) throws IOException { + return impl.read(b); } }