/** * Writes all necessary data for this entry. * * @since 1.1 */ public void closeEntry() throws IOException { if (entry == null) { return; } long realCrc = crc.getValue(); crc.reset(); if (entry.getMethod() == DEFLATED) { def.finish(); while (!def.finished()) { deflate(); } entry.setSize(def.getTotalIn()); entry.setComprSize(def.getTotalOut()); entry.setCrc(realCrc); def.reset(); written += entry.getCompressedSize(); } else if (raf == null) { if (entry.getCrc() != realCrc) { throw new SwcException.BadCRC(Long.toHexString(entry.getCrc()), Long.toHexString(realCrc)); } if (entry.getSize() != written - dataStart) { throw new SwcException.BadZipSize( entry.getName(), entry.getSize() + "", (written - dataStart) + ""); } } else { /* method is STORED and we used RandomAccessFile */ long size = written - dataStart; entry.setSize(size); entry.setComprSize(size); entry.setCrc(realCrc); } // If random access output, write the local file header containing // the correct CRC and compressed/uncompressed sizes if (raf != null) { long save = raf.getFilePointer(); raf.seek(localDataStart); writeOut((new ZipLong(entry.getCrc())).getBytes()); writeOut((new ZipLong(entry.getCompressedSize())).getBytes()); writeOut((new ZipLong(entry.getSize())).getBytes()); raf.seek(save); } writeDataDescriptor(entry); entry = null; }
/** * Begin writing next entry. * * @since 1.1 */ public void putNextEntry(ZipEntry ze) throws IOException { closeEntry(); entry = ze; entries.addElement(entry); if (entry.getMethod() == -1) { // not specified entry.setMethod(method); } if (entry.getTime() == -1) { // not specified entry.setTime(System.currentTimeMillis()); } // Size/CRC not required if RandomAccessFile is used if (entry.getMethod() == STORED && raf == null) { // these exceptions should never happen for us (as we always write to a file) // so they are not localized if (entry.getSize() == -1) { throw new RuntimeException( "uncompressed size is required for" + " STORED method when not writing to a" + " file"); } if (entry.getCrc() == -1) { throw new RuntimeException( "crc checksum is required for STORED" + " method when not writing to a file"); } entry.setComprSize(entry.getSize()); } if (entry.getMethod() == DEFLATED && hasCompressionLevelChanged) { def.setLevel(level); hasCompressionLevelChanged = false; } writeLocalFileHeader(entry); }
/** * Writes the data descriptor entry * * @since 1.1 */ protected void writeDataDescriptor(ZipEntry ze) throws IOException { if (ze.getMethod() != DEFLATED || raf != null) { return; } writeOut(DD_SIG.getBytes()); writeOut((new ZipLong(entry.getCrc())).getBytes()); writeOut((new ZipLong(entry.getCompressedSize())).getBytes()); writeOut((new ZipLong(entry.getSize())).getBytes()); written += 16; }
/** * Writes the central file header entry * * @since 1.1 */ protected void writeCentralFileHeader(ZipEntry ze) throws IOException { writeOut(CFH_SIG.getBytes()); written += 4; // version made by writeOut((new ZipShort((ze.getPlatform() << 8) | 20)).getBytes()); written += 2; // version needed to extract // general purpose bit flag if (ze.getMethod() == DEFLATED && raf == null) { // requires version 2 as we are going to store length info // in the data descriptor writeOut((new ZipShort(20)).getBytes()); // bit3 set to signal, we use a data descriptor writeOut((new ZipShort(8)).getBytes()); } else { writeOut((new ZipShort(10)).getBytes()); writeOut(ZERO); } written += 4; // compression method writeOut((new ZipShort(ze.getMethod())).getBytes()); written += 2; // last mod. time and date writeOut(toDosTime(ze.getTime()).getBytes()); written += 4; // CRC // compressed length // uncompressed length writeOut((new ZipLong(ze.getCrc())).getBytes()); writeOut((new ZipLong(ze.getCompressedSize())).getBytes()); writeOut((new ZipLong(ze.getSize())).getBytes()); written += 12; // file name length byte[] name = getBytes(ze.getName()); writeOut((new ZipShort(name.length)).getBytes()); written += 2; // extra field length byte[] extra = ze.getCentralDirectoryExtra(); writeOut((new ZipShort(extra.length)).getBytes()); written += 2; // file comment length String comm = ze.getComment(); if (comm == null) { comm = ""; } byte[] comment = getBytes(comm); writeOut((new ZipShort(comment.length)).getBytes()); written += 2; // disk number start writeOut(ZERO); written += 2; // internal file attributes writeOut((new ZipShort(ze.getInternalAttributes())).getBytes()); written += 2; // external file attributes writeOut((new ZipLong(ze.getExternalAttributes())).getBytes()); written += 4; // relative offset of LFH writeOut(offsets.get(ze).getBytes()); written += 4; // file name writeOut(name); written += name.length; // extra field writeOut(extra); written += extra.length; // file comment writeOut(comment); written += comment.length; }
/** * Writes the local file header entry * * @since 1.1 */ protected void writeLocalFileHeader(ZipEntry ze) throws IOException { offsets.put(ze, new ZipLong(written)); writeOut(LFH_SIG.getBytes()); written += 4; // version needed to extract // general purpose bit flag if (ze.getMethod() == DEFLATED && raf == null) { // requires version 2 as we are going to store length info // in the data descriptor writeOut((new ZipShort(20)).getBytes()); // bit3 set to signal, we use a data descriptor writeOut((new ZipShort(8)).getBytes()); } else { writeOut((new ZipShort(10)).getBytes()); writeOut(ZERO); } written += 4; // compression method writeOut((new ZipShort(ze.getMethod())).getBytes()); written += 2; // last mod. time and date writeOut(toDosTime(ze.getTime()).getBytes()); written += 4; // CRC // compressed length // uncompressed length localDataStart = written; if (ze.getMethod() == DEFLATED || raf != null) { writeOut(LZERO); writeOut(LZERO); writeOut(LZERO); } else { writeOut((new ZipLong(ze.getCrc())).getBytes()); writeOut((new ZipLong(ze.getSize())).getBytes()); writeOut((new ZipLong(ze.getSize())).getBytes()); } written += 12; // file name length byte[] name = getBytes(ze.getName()); writeOut((new ZipShort(name.length)).getBytes()); written += 2; // extra field length byte[] extra = ze.getLocalFileDataExtra(); writeOut((new ZipShort(extra.length)).getBytes()); written += 2; // file name writeOut(name); written += name.length; // extra field writeOut(extra); written += extra.length; dataStart = written; }