// package net.sf.zipme; class ZipArchive { /** * Creates an input stream reading the given zip entry as * uncompressed data. Normally zip entry should be an entry * returned by getEntry() or entries(). * This implementation returns null if the requested entry does not * exist. This decision is not obviously correct, however, it does * appear to mirror Sun's implementation, and it is consistant with * their javadoc. On the other hand, the old JCL book, 2nd Edition, * claims that this should return a "non-null ZIP entry". We have * chosen for now ignore the old book, as modern versions of Ant (an * important application) depend on this behaviour. See discussion * in this thread: * http://gcc.gnu.org/ml/java-patches/2004-q2/msg00602.html * @param entry the entry to create an InputStream for. * @return the input stream, or null if the requested entry does not exist. * @exception IOException if a i/o error occured. * @exception ZipException if the Zip archive is malformed. */ public InputStream getInputStream( ZipEntry entry) throws IOException { Hashtable entries=getEntries(); String name=entry.getName(); ZipEntry zipEntry=(ZipEntry)entries.get(name); if (zipEntry == null) return null; ZipArchive_PartialInputStream inp=new ZipArchive_PartialInputStream(buf,off,len); inp.seek(off + zipEntry.offset); if (inp.readLeInt() != LOCSIG) throw new ZipException("Wrong Local header signature: " + name); inp.skip(4); if (zipEntry.getMethod() != inp.readLeShort()) throw new ZipException("Compression method mismatch: " + name); inp.skip(16); int nameLen=inp.readLeShort(); int extraLen=inp.readLeShort(); inp.skip(nameLen + extraLen); inp.setLength((int)zipEntry.getCompressedSize()); int method=zipEntry.getMethod(); switch (method) { case ZipOutputStream.STORED: return inp; case ZipOutputStream.DEFLATED: inp.addDummyByte(); final Inflater inf=new Inflater(true); final int sz=(int)entry.getSize(); return new ZipArchive_InflaterInputStream(inp,inf,sz); default : throw new ZipException("Unknown compression method " + method); } } }