From d27a9520e6c954a6024c163bbe1d083e16c22c20 Mon Sep 17 00:00:00 2001 From: bothner Date: Thu, 6 May 1999 00:15:47 +0000 Subject: [PATCH] =?utf8?q?=EF=BF=BD=20=09*=20InflaterInputStream.java:=20?= =?utf8?q?=20New=20stub=20class.=20=09*=20ZipInputStream.java:=20=20New=20?= =?utf8?q?class.=20=20Partly=20works.=20=09*=20ZipConstants.java:=20=20Add?= =?utf8?q?=20two=20(internal)=20constants.=20=09*=20ZipEntry.java=20(timeF?= =?utf8?q?romDOS):=20=20New=20static=20(non-public)=20method.=20=09*=20Zip?= =?utf8?q?File.java:=20=20Make=20it=20mostly=20work,=20except=20for=20comp?= =?utf8?q?ression.=20=09*=20ZipOutputStream.java:=20=20Start=20implementat?= =?utf8?q?ion.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26795 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/java/util/zip/ZipFile.java | 111 +++++++++++++++++++++++++++-- libjava/java/util/zip/ZipOutputStream.java | 47 ++++++++++++ 2 files changed, 152 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 diff --git a/libjava/java/util/zip/ZipOutputStream.java b/libjava/java/util/zip/ZipOutputStream.java index 42cfb00..18f4d38 100644 --- a/libjava/java/util/zip/ZipOutputStream.java +++ b/libjava/java/util/zip/ZipOutputStream.java @@ -14,13 +14,60 @@ import java.io.*; public class ZipOutputStream extends DeflaterOutputStream implements ZipConstants { + ZipEntry current; + int method = DEFLATED; + int level = 3; // FIXME - should be DEFAULT_COMPRESSION + String comment; + + public static final int STORED = 0; + public static final int DEFLATED = 8; + public ZipOutputStream (OutputStream out) { super(out); } + public void setLevel (int level) { this.level = level; } + public void setMethod (int method) { this.method = method; } + public void setComment(String comment) { this.comment = comment; } + public void putNextEntry (ZipEntry entry) throws IOException { + put4(0x04034b50); + put2(0); // version - FIXME + put2(0); // bits - FIXME + if (entry.method < 0 ) + entry.method = method; + put2(entry.method); + put2(0); // time - FIXME + put2(0); // date - FIXME + put4((int) entry.crc); + put4((int) entry.compressedSize); // FIXME + put4((int) entry.size); // FIXME + put2(entry.name.length()); + put2(entry.extra == null ? 0 : entry.extra.length); + byte[] name = entry.name.getBytes("8859_1"); + out.write(name); + if (entry.extra != null) + out.write(entry.extra); throw new Error ("java.util.zip.ZipOutputStream.putNextEntry: not implemented"); } + + public void closeEntry () throws IOException + { + } + + private void put2 (int i) throws IOException + { + out.write (i); + out.write (i >> 8); + } + + private void put4 (int i) throws IOException + { + out.write (i); + out.write (i >> 8); + out.write (i >> 16); + out.write (i >> 24); + } } -- 2.7.4