/** * Returns an InputStream for reading the contents of the given entry. * * @param ze the entry to get the stream for. * @return a stream to read the entry from. * @throws IOException if unable to create an input stream from the zipenty * @throws ZipException if the zipentry uses an unsupported feature */ public java.io.InputStream getInputStream(ZipArchiveEntry ze) //throws IOException, ZipException { IAC_OffsetEntry offsetEntry = entries.get(ze); if (offsetEntry == null) { return(null); } ZipUtil.checkRequestedFeatures(ze); long start = offsetEntry.dataOffset; BoundedInputStream bis = new BoundedInputStream(this, start, ze.getCompressedSize()); switch (ze.getMethod()) { case ZipArchiveEntry.STORED: return(bis); case ZipArchiveEntry.DEFLATED: bis.addDummy(); return(new java.util.zip.InflaterInputStream(bis, new java.util.zip.Inflater(true))); default: throw new java.util.zip.ZipException("Found unsupported compression method " + ze.getMethod()); } }
/** * Walks through all recorded entries and adds the data available * from the local file header. * * <p>Also records the offsets for the data to read from the * entries.</p> */ private void resolveLocalFileHeaderData(java.util.Map <ZipArchiveEntry, IAC_NameAndComment> entriesWithoutUTF8Flag) //throws IOException { java.util.Enumeration <ZipArchiveEntry> e = getEntries(); while (e.hasMoreElements()) { ZipArchiveEntry ze = e.nextElement(); IAC_OffsetEntry offsetEntry = entries.get(ze); long offset = offsetEntry.headerOffset; archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH); byte[] b = new byte[SHORT]; archive.readFully(b); int fileNameLen = ZipShort.getValue(b); archive.readFully(b); int extraFieldLen = ZipShort.getValue(b); int lenToSkip = fileNameLen; while (lenToSkip > 0) { int skipped = archive.skipBytes(lenToSkip); if (skipped <= 0) { throw new java.lang.RuntimeException("failed to skip file name in" + " local file header"); } lenToSkip -= skipped; } byte[] localExtraData = new byte[extraFieldLen]; archive.readFully(localExtraData); ze.setExtra(localExtraData); /*dataOffsets.put(ze, * new Long(offset + LFH_OFFSET_FOR_FILENAME_LENGTH + SHORT + SHORT + fileNameLen + extraFieldLen)); */ offsetEntry.dataOffset = offset + LFH_OFFSET_FOR_FILENAME_LENGTH + SHORT + SHORT + fileNameLen + extraFieldLen; if (entriesWithoutUTF8Flag.containsKey(ze)) { String orig = ze.getName(); IAC_NameAndComment nc = (IAC_NameAndComment)entriesWithoutUTF8Flag.get(ze); ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name, nc.comment); if (!orig.equals(ze.getName())) { nameMap.remove(orig); nameMap.put(ze.getName(), ze); } } } }
public int compare(ZipArchiveEntry e1, ZipArchiveEntry e2) { if (e1 == e2) { return(0); } IAC_OffsetEntry off1 = (IAC_OffsetEntry)root.entries.get(e1); IAC_OffsetEntry off2 = (IAC_OffsetEntry)root.entries.get(e2); if (off1 == null) { return(1); } if (off2 == null) { return(-1); } long val = (off1.headerOffset - off2.headerOffset); return(val == 0 ? 0 : val < 0 ? -1 : +1); }
/** * Reads the central directory of the given archive and populates * the internal tables with ZipArchiveEntry instances. * * <p>The ZipArchiveEntrys will know all data that can be obtained from * the central directory alone, but not the data that requires the * local file header or additional data to be read.</p> * * @return a Map<ZipArchiveEntry, NameAndComment>> of * zipentries that didn't have the language encoding flag set when * read. */ private java.util.Map <ZipArchiveEntry, IAC_NameAndComment> populateFromCentralDirectory() //throws IOException { java.util.HashMap <ZipArchiveEntry, IAC_NameAndComment> noUTF8Flag = new java.util.HashMap <ZipArchiveEntry, IAC_NameAndComment>(); positionAtCentralDirectory(); byte[] cfh = new byte[CFH_LEN]; byte[] signatureBytes = new byte[WORD]; archive.readFully(signatureBytes); long sig = ZipLong.getValue(signatureBytes); long cfhSig = ZipLong.getValue(ZipArchiveOutputStream.CFH_SIG); if (sig != cfhSig && startsWithLocalFileHeader()) { throw new java.io.IOException("central directory is empty, can't expand" + " corrupt archive."); } while (sig == cfhSig) { archive.readFully(cfh); int off = 0; ZipArchiveEntry ze = new ZipArchiveEntry(); int versionMadeBy = ZipShort.getValue(cfh, off); off += SHORT; ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK); off += SHORT; // skip version info GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(cfh, off); bool hasUTF8Flag = gpFlag.usesUTF8ForNames(); ZipEncoding entryEncoding = hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding; ze.setGeneralPurposeBit(gpFlag); off += SHORT; ze.setMethod(ZipShort.getValue(cfh, off)); off += SHORT; // FIXME this is actually not very cpu cycles friendly as we are converting from // dos to java while the underlying Sun implementation will convert // from java to dos time for internal storage... long time = ZipUtil.dosToJavaTime(ZipLong.getValue(cfh, off)); ze.setTime(time); off += WORD; ze.setCrc(ZipLong.getValue(cfh, off)); off += WORD; ze.setCompressedSize(ZipLong.getValue(cfh, off)); off += WORD; ze.setSize(ZipLong.getValue(cfh, off)); off += WORD; int fileNameLen = ZipShort.getValue(cfh, off); off += SHORT; int extraLen = ZipShort.getValue(cfh, off); off += SHORT; int commentLen = ZipShort.getValue(cfh, off); off += SHORT; off += SHORT; // disk number ze.setInternalAttributes(ZipShort.getValue(cfh, off)); off += SHORT; ze.setExternalAttributes(ZipLong.getValue(cfh, off)); off += WORD; byte[] fileName = new byte[fileNameLen]; archive.readFully(fileName); ze.setName(entryEncoding.decode(fileName)); // LFH offset, IAC_OffsetEntry offset = new IAC_OffsetEntry(); offset.headerOffset = ZipLong.getValue(cfh, off); // data offset will be filled later entries.put(ze, offset); nameMap.put(ze.getName(), ze); byte[] cdExtraData = new byte[extraLen]; archive.readFully(cdExtraData); ze.setCentralDirectoryExtra(cdExtraData); byte[] comment = new byte[commentLen]; archive.readFully(comment); ze.setComment(entryEncoding.decode(comment)); archive.readFully(signatureBytes); sig = ZipLong.getValue(signatureBytes); if (!hasUTF8Flag && useUnicodeExtraFields) { noUTF8Flag.put(ze, new IAC_NameAndComment(fileName, comment)); } } return(noUTF8Flag); }