diff options
Diffstat (limited to 'libjava/java/util/zip/ZipFile.java')
-rw-r--r-- | libjava/java/util/zip/ZipFile.java | 111 |
1 files changed, 105 insertions, 6 deletions
diff --git a/libjava/java/util/zip/ZipFile.java b/libjava/java/util/zip/ZipFile.java index 75f0a3d..9085ec9 100644 --- a/libjava/java/util/zip/ZipFile.java +++ b/libjava/java/util/zip/ZipFile.java @@ -9,23 +9,91 @@ details. */ package java.util.zip; import java.io.*; -/** JUST AN INCOMPLETE STUB! */ +/** UNFINISHED, but can read non-comrepssed .zip archives. */ public class ZipFile implements ZipConstants { - String name; ZipEntry entries; + int numEntries; + RandomAccessFile file; + String name; public ZipFile (String fname) throws IOException { + file = new RandomAccessFile(fname, "r"); name = fname; - // FIXME } public ZipFile (File f) throws IOException { - this(f.getPath()); + file = new RandomAccessFile(f, "r"); + name = f.getName(); + } + + void readDirectory () throws IOException + { + long size = file.length (); + if (size < ZipConstants.END_CENTRAL_DIR_SIZE) + throw new IOException ("zipfile too short"); + // We do not handle a "zipfile comment", which the appnote says can + // be at the end of a .zip file. We could handle this by seeking + // to the beginning and reading forwards. + file.seek(size - ZipConstants.END_CENTRAL_DIR_SIZE); + if (file.read() != 'P' + || file.read() != 'K' + || file.read() != '\005' + || file.read() != '\006') + throw new IOException("not a valid zipfile"); + file.skipBytes(6); + numEntries = readu2(); + int dir_size = read4 (); // Read "size of the central directory". + file.seek(size - (dir_size + ZipConstants.END_CENTRAL_DIR_SIZE)); + + ZipEntry last = null; + for (int i = 0; i < numEntries; i++) + { + file.skipBytes(10); + int method = readu2(); + int modtime = readu2(); + int moddate = readu2(); + int crc = read4(); + int compressedSize = read4(); + int uncompressedSize = read4(); + int filenameLength = readu2(); + int extraLength = readu2(); + int commentLength = readu2(); + int diskNumberStart = readu2(); + int intAttributes = readu2(); + int extAttributes = read4(); + int relativeOffset = read4(); + byte[] bname = new byte[filenameLength]; + file.readFully(bname); + ZipEntry entry = new ZipEntry(new String(bname, "8859_1")); + if (extraLength > 0) + { + byte[] bextra = new byte[extraLength]; + file.readFully(bextra); + entry.extra = bextra; + } + if (commentLength > 0) + { + byte[] bcomment = new byte[commentLength]; + file.readFully(bcomment); + entry.comment = new String(bcomment, "8859_1"); + } + entry.compressedSize = compressedSize; + entry.size = uncompressedSize; + entry.crc = (long) crc & 0xffffffffL; + entry.method = method; + entry.relativeOffset = relativeOffset; + entry.time = ZipEntry.timeFromDOS(moddate, modtime); + if (last == null) + entries = entry; + else + last.next = entry; + last = entry; + } } public java.util.Enumeration entries() @@ -35,7 +103,10 @@ public class ZipFile implements ZipConstants public void close() throws IOException { - // FIXME + // FIXME - check this + file.close(); + entries = null; + numEntries = 0; } public ZipEntry getEntry(String name) @@ -50,10 +121,38 @@ public class ZipFile implements ZipConstants public InputStream getInputStream(ZipEntry ze) throws IOException { - return null; // FIXME + // FIXME - does not handle compression! + byte[] buffer = new byte[(int) ze.getSize()]; + int data_offset = ZipConstants.LOCAL_FILE_HEADER_SIZE + name.length(); + if (ze.extra != null) + data_offset += ze.extra.length; + file.seek(ze.relativeOffset + data_offset); + file.readFully(buffer); + return new ByteArrayInputStream(buffer); } public String getName () { return name; } + + private int readu2 () throws IOException + { + int byte0 = file.read(); + int byte1 = file.read(); + if (byte0 < 0 || byte1 < 0) + throw new EOFException(".zip archive ended prematurely"); + return ((byte1 & 0xFF) << 8) | (byte0 & 0xFF); + } + + private int read4 () throws IOException + { + int byte0 = file.read(); + int byte1 = file.read(); + int byte2 = file.read(); + int byte3 = file.read(); + if (byte3 < 0) + throw new EOFException(".zip archive ended prematurely"); + return ((byte3 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + + ((byte1 & 0xFF) << 8) + (byte0 & 0xFF); + } } class ZipEnumeration implements java.util.Enumeration |