/** * Searches for the "End of central dir record", parses * it and positions the stream at the first central directory * record. */ private void positionAtCentralDirectory() //throws IOException { bool found = false; long off = archive.length() - MIN_EOCD_SIZE; long stopSearching = java.lang.Math.max(0L, archive.length() - MAX_EOCD_SIZE); if (off >= 0) { archive.seek(off); byte[] sig = ZipArchiveOutputStream.EOCD_SIG; int curr = archive.read(); while (off >= stopSearching && curr != -1) { if (curr == sig[POS_0]) { curr = archive.read(); if (curr == sig[POS_1]) { curr = archive.read(); if (curr == sig[POS_2]) { curr = archive.read(); if (curr == sig[POS_3]) { found = true; break; } } } } archive.seek(--off); curr = archive.read(); } } if (!found) { throw new java.util.zip.ZipException("archive is not a ZIP archive"); } archive.seek(off + CFD_LOCATOR_OFFSET); byte[] cfdOffset = new byte[WORD]; archive.readFully(cfdOffset); archive.seek(ZipLong.getValue(cfdOffset)); }
/** {@inheritDoc} */ public void parseFromLocalFileData(byte[] buffer, int offset, int length) //throws ZipException { if (length < 5) { throw new java.util.zip.ZipException("UniCode path extra data must have at least 5 bytes."); } int version = buffer[offset]; if (version != 0x01) { throw new java.util.zip.ZipException("Unsupported version [" + version + "] for UniCode path extra data."); } nameCRC32 = ZipLong.getValue(buffer, offset + 1); unicodeName = new byte[length - 5]; java.lang.SystemJ.arraycopy(buffer, offset + 5, unicodeName, 0, length - 5); data = null; }
/** * Populate data from this array as if it was in local file data. * @param data an array of bytes * @param offset the start offset * @param length the number of bytes in the array from offset * @throws ZipException on error */ public void parseFromLocalFileData(byte[] data, int offset, int length) //throws ZipException { long givenChecksum = ZipLong.getValue(data, offset); byte[] tmp = new byte[length - WORD]; java.lang.SystemJ.arraycopy(data, offset + WORD, tmp, 0, length - WORD); crc.reset(); crc.update(tmp); long realChecksum = crc.getValue(); if (givenChecksum != realChecksum) { throw new java.util.zip.ZipException("bad CRC checksum " + java.lang.Long.toHexString(givenChecksum) + " instead of " + java.lang.Long.toHexString(realChecksum)); } int newMode = ZipShort.getValue(tmp, 0); // CheckStyle:MagicNumber OFF byte[] linkArray = new byte[(int)ZipLong.getValue(tmp, 2)]; uid = ZipShort.getValue(tmp, 6); gid = ZipShort.getValue(tmp, 8); if (linkArray.Length == 0) { link = ""; } else { java.lang.SystemJ.arraycopy(tmp, 10, linkArray, 0, linkArray.Length); link = System.Text.ASCIIEncoding.ASCII.GetString(linkArray); // Uses default charset - see class Javadoc } // CheckStyle:MagicNumber ON setDirectory((newMode & UnixStat.DIR_FLAG) != 0); setMode(newMode); }
/** * 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); }
public ZipArchiveEntry getNextZipEntry() //throws IOException { if (closed || hitCentralDirectory) { return(null); } if (current != null) { closeEntry(); } byte[] lfh = new byte[LFH_LEN]; try { readFully(lfh); } catch (java.io.EOFException) { return(null); } ZipLong sig = new ZipLong(lfh); if (sig.equals(ZipLong.CFH_SIG)) { hitCentralDirectory = true; return(null); } if (!sig.equals(ZipLong.LFH_SIG)) { return(null); } int off = WORD; current = new ZipArchiveEntry(); int versionMadeBy = ZipShort.getValue(lfh, off); off += SHORT; current.setPlatform((versionMadeBy >> ZipFile.BYTE_SHIFT) & ZipFile.NIBLET_MASK); GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(lfh, off); bool hasUTF8Flag = gpFlag.usesUTF8ForNames(); ZipEncoding entryEncoding = hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding; hasDataDescriptor = gpFlag.usesDataDescriptor(); current.setGeneralPurposeBit(gpFlag); off += SHORT; current.setMethod(ZipShort.getValue(lfh, off)); off += SHORT; long time = ZipUtil.dosToJavaTime(ZipLong.getValue(lfh, off)); current.setTime(time); off += WORD; if (!hasDataDescriptor) { current.setCrc(ZipLong.getValue(lfh, off)); off += WORD; current.setCompressedSize(ZipLong.getValue(lfh, off)); off += WORD; current.setSize(ZipLong.getValue(lfh, off)); off += WORD; } else { off += 3 * WORD; } int fileNameLen = ZipShort.getValue(lfh, off); off += SHORT; int extraLen = ZipShort.getValue(lfh, off); off += SHORT; byte[] fileName = new byte[fileNameLen]; readFully(fileName); current.setName(entryEncoding.decode(fileName)); byte[] extraData = new byte[extraLen]; readFully(extraData); current.setExtra(extraData); if (!hasUTF8Flag && useUnicodeExtraFields) { ZipUtil.setNameAndCommentFromExtraFields(current, fileName, null); } return(current); }
/** * Convert a DOS date/time field to a Date object. * * @param zipDosTime contains the stored DOS time. * @return a Date instance corresponding to the given time. */ public static java.util.Date fromDosTime(ZipLong zipDosTime) { long dosTime = zipDosTime.getValue(); return(new java.util.Date(dosToJavaTime(dosTime))); }
/** * Create instance from the four bytes starting at offset. * @param bytes the bytes to store as a ZipLong * @param offset the offset to start */ public ZipLong(byte[] bytes, int offset) { value = ZipLong.getValue(bytes, offset); }
/** * Create instance from bytes. * @param bytes the bytes to store as a ZipLong */ public ZipLong(byte[] bytes) { value = ZipLong.getValue(bytes, 0); }