diff options
author | Mark Wielaard <mark@klomp.org> | 2002-12-03 22:06:31 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2002-12-03 22:06:31 +0000 |
commit | 9c1180ea42444a74342889f3322d38cbbd08ae2e (patch) | |
tree | 730056898d88a253ce543c7b06b7c20328b734b8 /libjava/java/util | |
parent | 6e1be6b19c65ea41fa3772c835477d59429f94a3 (diff) | |
download | gcc-9c1180ea42444a74342889f3322d38cbbd08ae2e.zip gcc-9c1180ea42444a74342889f3322d38cbbd08ae2e.tar.gz gcc-9c1180ea42444a74342889f3322d38cbbd08ae2e.tar.bz2 |
JarFile.java (manifest): Not final.
* java/util/jar/JarFile.java (manifest): Not final.
(manifestRead): New field.
(JarFile): Don't read Manifest in constructor.
(getManifest): New method.
(JarEnumeration.nextElement): Use new method.
(getEntry): Likewise.
* java/util/zip/ZipFile.java (name): Final.
(raf): Likewsie.
(entries): Change type to Hashtable.
(closed): New field.
(ZipFile): Don't read enties in constructor.
(readEntries): Use Hashtable.
(close): Set new close flag and set entries to null inside
synchronized block.
(entries): Contruct enumeration using new getEntries() method and
entries Hashtable.
(getEntryIndex): Removed.
(getEntries): New method.
(getEntry): Use new getEntries() method and entries Hastable.
(getInputStream): Likewise.
(size): Return getEntries().size().
(ZipEntryEnumeration): Wrap entries Hashtable elements.
* java/util/zip/ZipEntry.java (cal): Don't initialize.
(time): Removed
(dostime): New field.
(zipFileIndex): Removed.
(ZipEntry(ZipEntry)): Copy dostime.
(setDOSTime): Now final and doesn't convert dos time.
(getDOSTime): Likewise.
(setTime): Convert dos time.
(getTime): Likewise.
(getCalendar): New method.
(setExtra): Use setTime().
* java/util/zip/ZipInputStream.java (getNextEntry): Format error msg.
From-SVN: r59785
Diffstat (limited to 'libjava/java/util')
-rw-r--r-- | libjava/java/util/jar/JarFile.java | 70 | ||||
-rw-r--r-- | libjava/java/util/zip/ZipEntry.java | 99 | ||||
-rw-r--r-- | libjava/java/util/zip/ZipFile.java | 137 | ||||
-rw-r--r-- | libjava/java/util/zip/ZipInputStream.java | 2 |
4 files changed, 180 insertions, 128 deletions
diff --git a/libjava/java/util/jar/JarFile.java b/libjava/java/util/jar/JarFile.java index 25179d2..d6fd984 100644 --- a/libjava/java/util/jar/JarFile.java +++ b/libjava/java/util/jar/JarFile.java @@ -67,18 +67,22 @@ public class JarFile extends ZipFile /** * The manifest of this file, if any, otherwise null. - * Read by the constructor. + * Read when first needed. */ - private final Manifest manifest; + private Manifest manifest; - /** Wether to verify the manifest and all entries */ + /** Wether to verify the manifest and all entries. */ private boolean verify; + /** Wether the has already been loaded. */ + private boolean manifestRead = false; + // Constructors /** - * Creates a new JarFile, tries to read the manifest and if the manifest - * exists verifies it. + * Creates a new JarFile. All jar entries are verified (when a Manifest file + * for this JarFile exists). You need to actually open and read the complete + * jar entry (with <code>getInputStream()</code>) to check its signature. * * @param fileName the name of the file to open * @exception FileNotFoundException if the fileName cannot be found @@ -90,8 +94,10 @@ public class JarFile extends ZipFile } /** - * Creates a new JarFile, tries to read the manifest and if the manifest - * exists and verify is true verfies it. + * Creates a new JarFile. If verify is true then all jar entries are + * verified (when a Manifest file for this JarFile exists). You need to + * actually open and read the complete jar entry + * (with <code>getInputStream()</code>) to check its signature. * * @param fileName the name of the file to open * @param verify checks manifest and entries when true and a manifest @@ -103,14 +109,12 @@ public class JarFile extends ZipFile FileNotFoundException, IOException { super(fileName); - manifest = readManifest(); - if (verify) - verify(); } /** - * Creates a new JarFile, tries to read the manifest and if the manifest - * exists verifies it. + * Creates a new JarFile. All jar entries are verified (when a Manifest file + * for this JarFile exists). You need to actually open and read the complete + * jar entry (with <code>getInputStream()</code>) to check its signature. * * @param file the file to open as a jar file * @exception FileNotFoundException if the file does not exits @@ -122,8 +126,10 @@ public class JarFile extends ZipFile } /** - * Creates a new JarFile, tries to read the manifest and if the manifest - * exists and verify is true verfies it. + * Creates a new JarFile. If verify is true then all jar entries are + * verified (when a Manifest file for this JarFile exists). You need to + * actually open and read the complete jar entry + * (with <code>getInputStream()</code>) to check its signature. * * @param file the file to open to open as a jar file * @param verify checks manifest and entries when true and a manifest @@ -135,13 +141,13 @@ public class JarFile extends ZipFile IOException { super(file); - manifest = readManifest(); - if (verify) - verify(); } /** - * Creates a new JarFile with the indicated mode, tries to read the + * Creates a new JarFile with the indicated mode. If verify is true then + * all jar entries are verified (when a Manifest file for this JarFile + * exists). You need to actually open and read the complete jar entry + * (with <code>getInputStream()</code>) to check its signature. * manifest and if the manifest exists and verify is true verfies it. * * @param file the file to open to open as a jar file @@ -159,9 +165,6 @@ public class JarFile extends ZipFile FileNotFoundException, IOException, IllegalArgumentException { super(file, mode); - manifest = readManifest(); - if (verify) - verify(); } // Methods @@ -241,6 +244,16 @@ public class JarFile extends ZipFile { ZipEntry zip = (ZipEntry) entries.nextElement(); JarEntry jar = new JarEntry(zip); + Manifest manifest; + try + { + manifest = getManifest(); + } + catch (IOException ioe) + { + manifest = null; + } + if (manifest != null) { jar.attr = manifest.getAttributes(jar.getName()); @@ -261,6 +274,16 @@ public class JarFile extends ZipFile if (entry != null) { JarEntry jarEntry = new JarEntry(entry); + Manifest manifest; + try + { + manifest = getManifest(); + } + catch (IOException ioe) + { + manifest = null; + } + if (manifest != null) { jarEntry.attr = manifest.getAttributes(name); @@ -301,8 +324,11 @@ public class JarFile extends ZipFile * Returns the manifest for this JarFile or null when the JarFile does not * contain a manifest file. */ - public Manifest getManifest() + public Manifest getManifest() throws IOException { + if (!manifestRead) + manifest = readManifest(); + return manifest; } } diff --git a/libjava/java/util/zip/ZipEntry.java b/libjava/java/util/zip/ZipEntry.java index 5a43b1f..c9f1b1d 100644 --- a/libjava/java/util/zip/ZipEntry.java +++ b/libjava/java/util/zip/ZipEntry.java @@ -55,19 +55,18 @@ public class ZipEntry implements ZipConstants, Cloneable private static int KNOWN_CRC = 4; private static int KNOWN_TIME = 8; - private static Calendar cal = Calendar.getInstance(); + private static Calendar cal; private String name; private int size; private int compressedSize; private int crc; - private int time; + private int dostime; private short known = 0; private short method = -1; private byte[] extra = null; private String comment = null; - int zipFileIndex = -1; /* used by ZipFile */ int flags; /* used by ZipOutputStream */ int offset; /* used by ZipFile and ZipOutputStream */ @@ -104,53 +103,24 @@ public class ZipEntry implements ZipConstants, Cloneable size = e.size; compressedSize = e.compressedSize; crc = e.crc; - time = e.time; + dostime = e.dostime; method = e.method; extra = e.extra; comment = e.comment; } - void setDOSTime(int dostime) + final void setDOSTime(int dostime) { - int sec = 2 * (dostime & 0x1f); - int min = (dostime >> 5) & 0x3f; - int hrs = (dostime >> 11) & 0x1f; - int day = (dostime >> 16) & 0x1f; - int mon = ((dostime >> 21) & 0xf) - 1; - int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */ - - // Guard against invalid or missing date causing - // IndexOutOfBoundsException. - try - { - synchronized (cal) - { - cal.set(year, mon, day, hrs, min, sec); - time = (int) (cal.getTime().getTime() / 1000L); - } - known |= KNOWN_TIME; - } - catch (RuntimeException ex) - { - /* Ignore illegal time stamp */ - known &= ~KNOWN_TIME; - } + this.dostime = dostime; + known |= KNOWN_TIME; } - int getDOSTime() + final int getDOSTime() { if ((known & KNOWN_TIME) == 0) return 0; - synchronized (cal) - { - cal.setTime(new Date(time*1000L)); - return (cal.get(cal.YEAR) - 1980 & 0x7f) << 25 - | (cal.get(cal.MONTH) + 1) << 21 - | (cal.get(cal.DAY_OF_MONTH)) << 16 - | (cal.get(cal.HOUR_OF_DAY)) << 11 - | (cal.get(cal.MINUTE)) << 5 - | (cal.get(cal.SECOND)) >> 1; - } + else + return dostime; } /** @@ -190,7 +160,18 @@ public class ZipEntry implements ZipConstants, Cloneable */ public void setTime(long time) { - this.time = (int) (time / 1000L); + Calendar cal = getCalendar(); + synchronized (cal) + { + cal.setTime(new Date(time*1000L)); + dostime = (cal.get(cal.YEAR) - 1980 & 0x7f) << 25 + | (cal.get(cal.MONTH) + 1) << 21 + | (cal.get(cal.DAY_OF_MONTH)) << 16 + | (cal.get(cal.HOUR_OF_DAY)) << 11 + | (cal.get(cal.MINUTE)) << 5 + | (cal.get(cal.SECOND)) >> 1; + } + dostime = (int) (dostime / 1000L); this.known |= KNOWN_TIME; } @@ -200,7 +181,39 @@ public class ZipEntry implements ZipConstants, Cloneable */ public long getTime() { - return (known & KNOWN_TIME) != 0 ? time * 1000L : -1; + if ((known & KNOWN_TIME) == 0) + return -1; + + int sec = 2 * (dostime & 0x1f); + int min = (dostime >> 5) & 0x3f; + int hrs = (dostime >> 11) & 0x1f; + int day = (dostime >> 16) & 0x1f; + int mon = ((dostime >> 21) & 0xf) - 1; + int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */ + + try + { + cal = getCalendar(); + synchronized (cal) + { + cal.set(year, mon, day, hrs, min, sec); + return cal.getTime().getTime(); + } + } + catch (RuntimeException ex) + { + /* Ignore illegal time stamp */ + known &= ~KNOWN_TIME; + return -1; + } + } + + private static synchronized Calendar getCalendar() + { + if (cal == null) + cal = Calendar.getInstance(); + + return cal; } /** @@ -320,11 +333,11 @@ public class ZipEntry implements ZipConstants, Cloneable int flags = extra[pos]; if ((flags & 1) != 0) { - time = ((extra[pos+1] & 0xff) + long time = ((extra[pos+1] & 0xff) | (extra[pos+2] & 0xff) << 8 | (extra[pos+3] & 0xff) << 16 | (extra[pos+4] & 0xff) << 24); - known |= KNOWN_TIME; + setTime(time); } } pos += len; diff --git a/libjava/java/util/zip/ZipFile.java b/libjava/java/util/zip/ZipFile.java index 2eb1156..eb79d03 100644 --- a/libjava/java/util/zip/ZipFile.java +++ b/libjava/java/util/zip/ZipFile.java @@ -46,6 +46,7 @@ import java.io.IOException; import java.io.EOFException; import java.io.RandomAccessFile; import java.util.Enumeration; +import java.util.Hashtable; import java.util.NoSuchElementException; /** @@ -61,21 +62,26 @@ import java.util.NoSuchElementException; public class ZipFile implements ZipConstants { - /** Mode flag to open a zip file for reading - * + /** + * Mode flag to open a zip file for reading. */ - public static final int OPEN_READ = 0x1; - /** Mode flag to delete a zip file after reading - * + /** + * Mode flag to delete a zip file after reading. */ - public static final int OPEN_DELETE = 0x4; - private String name; - RandomAccessFile raf; - ZipEntry[] entries; + // Name of this zip file. + private final String name; + + // File from which zip entries are read. + private final RandomAccessFile raf; + + // The entries of this zip file when initialized and not yet closed. + private Hashtable entries; + + private boolean closed = false; /** * Opens a Zip file with the given name for reading. @@ -87,7 +93,6 @@ public class ZipFile implements ZipConstants { this.raf = new RandomAccessFile(name, "r"); this.name = name; - readEntries(); } /** @@ -100,7 +105,6 @@ public class ZipFile implements ZipConstants { this.raf = new RandomAccessFile(file, "r"); this.name = file.getName(); - readEntries(); } /** @@ -130,7 +134,6 @@ public class ZipFile implements ZipConstants } this.raf = new RandomAccessFile(file, "r"); this.name = file.getName(); - readEntries(); } /** @@ -160,7 +163,7 @@ public class ZipFile implements ZipConstants /** * Read the central directory of a zip file and fill the entries - * array. This is called exactly once by the constructors. + * array. This is called exactly once when first needed. * @exception IOException if a i/o error occured. * @exception ZipException if the central directory is malformed */ @@ -187,7 +190,7 @@ public class ZipFile implements ZipConstants throw new EOFException(name); int centralOffset = readLeInt(raf); - entries = new ZipEntry[count]; + entries = new Hashtable(count); raf.seek(centralOffset); byte[] ebs = new byte[24]; ByteArrayInputStream ebais = new ByteArrayInputStream(ebs); @@ -236,9 +239,8 @@ public class ZipFile implements ZipConstants raf.readFully(buffer, 0, commentLen); entry.setComment(new String(buffer, 0, commentLen)); } - entry.zipFileIndex = i; entry.offset = offset; - entries[i] = entry; + entries.put(name, entry); } } @@ -250,9 +252,10 @@ public class ZipFile implements ZipConstants */ public void close() throws IOException { - entries = null; synchronized (raf) { + closed = true; + entries = null; raf.close(); } } @@ -262,17 +265,34 @@ public class ZipFile implements ZipConstants */ public Enumeration entries() { - if (entries == null) - throw new IllegalStateException("ZipFile has closed: " + name); - return new ZipEntryEnumeration(entries); + try + { + return new ZipEntryEnumeration(getEntries().elements()); + } + catch (IOException ioe) + { + return null; + } } - private int getEntryIndex(String name) + /** + * Checks that the ZipFile is still open and reads entries when necessary. + * + * @exception IllegalStateException when the ZipFile has already been closed. + * @exception IOEexception when the entries could not be read. + */ + private Hashtable getEntries() throws IOException { - for (int i = 0; i < entries.length; i++) - if (name.equals(entries[i].getName())) - return i; - return -1; + synchronized(raf) + { + if (closed) + throw new IllegalStateException("ZipFile has closed: " + name); + + if (entries == null) + readEntries(); + + return entries; + } } /** @@ -283,10 +303,16 @@ public class ZipFile implements ZipConstants * @see #entries */ public ZipEntry getEntry(String name) { - if (entries == null) - throw new IllegalStateException("ZipFile has closed: " + name); - int index = getEntryIndex(name); - return index >= 0 ? (ZipEntry) entries[index].clone() : null; + try + { + Hashtable entries = getEntries(); + ZipEntry entry = (ZipEntry) entries.get(name); + return entry != null ? (ZipEntry) entry.clone() : null; + } + catch (IOException ioe) + { + return null; + } } /** @@ -334,21 +360,16 @@ public class ZipFile implements ZipConstants */ public InputStream getInputStream(ZipEntry entry) throws IOException { - if (entries == null) - throw new IllegalStateException("ZipFile has closed"); - int index = entry.zipFileIndex; - if (index < 0 || index >= entries.length - || entries[index].getName() != entry.getName()) - { - index = getEntryIndex(entry.getName()); - if (index < 0) - throw new NoSuchElementException(); - } - - long start = checkLocalHeader(entries[index]); - int method = entries[index].getMethod(); + Hashtable entries = getEntries(); + String name = entry.getName(); + ZipEntry zipEntry = (ZipEntry) entries.get(name); + if (zipEntry == null) + throw new NoSuchElementException(name); + + long start = checkLocalHeader(zipEntry); + int method = zipEntry.getMethod(); InputStream is = new PartialInputStream - (raf, start, entries[index].getCompressedSize()); + (raf, start, zipEntry.getCompressedSize()); switch (method) { case ZipOutputStream.STORED: @@ -375,42 +396,34 @@ public class ZipFile implements ZipConstants { try { - return entries.length; + return getEntries().size(); } - catch (NullPointerException ex) + catch (IOException ioe) { - throw new IllegalStateException("ZipFile has closed"); + return 0; } } private static class ZipEntryEnumeration implements Enumeration { - ZipEntry[] array; - int ptr = 0; + private final Enumeration elements; - public ZipEntryEnumeration(ZipEntry[] arr) + public ZipEntryEnumeration(Enumeration elements) { - array = arr; + this.elements = elements; } public boolean hasMoreElements() { - return ptr < array.length; + return elements.hasMoreElements(); } public Object nextElement() { - try - { - /* We return a clone, just to be safe that the user doesn't - * change the entry. - */ - return array[ptr++].clone(); - } - catch (ArrayIndexOutOfBoundsException ex) - { - throw new NoSuchElementException(); - } + /* We return a clone, just to be safe that the user doesn't + * change the entry. + */ + return ((ZipEntry)elements.nextElement()).clone(); } } diff --git a/libjava/java/util/zip/ZipInputStream.java b/libjava/java/util/zip/ZipInputStream.java index c9a6c01..c490597 100644 --- a/libjava/java/util/zip/ZipInputStream.java +++ b/libjava/java/util/zip/ZipInputStream.java @@ -151,7 +151,7 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants return null; } if (header != LOCSIG) - throw new ZipException("Wrong Local header signature" + throw new ZipException("Wrong Local header signature: " + Integer.toHexString(header)); /* skip version */ readLeShort(); |