aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/util/zip/ZipFile.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/util/zip/ZipFile.java')
-rw-r--r--libjava/java/util/zip/ZipFile.java111
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