private void readDataDescr() throws IOException { if (readLeInt() != EXTSIG) throw new ZipException("Data descriptor signature not found"); entry.setCrc(readLeInt() & 0xffffffffL); csize = readLeInt(); size = readLeInt(); entry.setSize(size & 0xffffffffL); entry.setCompressedSize(csize & 0xffffffffL); }
/** * Reads a block of bytes from the current zip entry. * * @return the number of bytes read (may be smaller, even before EOF), or -1 on EOF. * @exception IOException if a i/o error occured. * @exception ZipException if the deflated stream is corrupted. */ public int read(byte[] b, int off, int len) throws IOException { if (len == 0) return 0; if (crc == null) throw new IOException("Stream closed."); if (entry == null) return -1; boolean finished = false; switch (method) { case ZipOutputStream.DEFLATED: len = super.read(b, off, len); if (len < 0) { if (!inf.finished()) throw new ZipException("Inflater not finished!?"); avail = inf.getRemaining(); if ((flags & 8) != 0) readDataDescr(); if (inf.getTotalIn() != csize || inf.getTotalOut() != size) throw new ZipException( "size mismatch: " + csize + ";" + size + " <-> " + inf.getTotalIn() + ";" + inf.getTotalOut()); inf.reset(); finished = true; } break; case ZipOutputStream.STORED: if (len > csize && csize >= 0) len = csize; len = readBuf(b, off, len); if (len > 0) { csize -= len; size -= len; } if (csize == 0) finished = true; else if (len < 0) throw new ZipException("EOF in stored block"); break; } if (len > 0) crc.update(b, off, len); if (finished) { if ((crc.getValue() & 0xffffffffL) != entry.getCrc()) throw new ZipException("CRC mismatch"); crc.reset(); entry = null; entryAtEOF = true; } return len; }
/** * Open the next entry from the zip archive, and return its description. If the previous entry * wasn't closed, this method will close it. */ public ZipEntry getNextEntry() throws IOException { if (crc == null) throw new IOException("Stream closed."); if (entry != null) closeEntry(); int header = readLeInt(); if (header == CENSIG) { /* Central Header reached. */ close(); return null; } if (header != LOCSIG) throw new ZipException("Wrong Local header signature: " + Integer.toHexString(header)); /* skip version */ readLeShort(); flags = readLeShort(); method = readLeShort(); int dostime = readLeInt(); int crc = readLeInt(); csize = readLeInt(); size = readLeInt(); int nameLen = readLeShort(); int extraLen = readLeShort(); if (method == ZipOutputStream.STORED && csize != size) throw new ZipException("Stored, but compressed != uncompressed"); byte[] buffer = new byte[nameLen]; readFully(buffer); String name; try { name = new String(buffer, "UTF-8"); } catch (UnsupportedEncodingException uee) { throw new Error(uee.toString()); } entry = createZipEntry(name); entryAtEOF = false; entry.setMethod(method); if ((flags & 8) == 0) { entry.setCrc(crc & 0xffffffffL); entry.setSize(size & 0xffffffffL); entry.setCompressedSize(csize & 0xffffffffL); } entry.setDOSTime(dostime); if (extraLen > 0) { byte[] extra = new byte[extraLen]; readFully(extra); entry.setExtra(extra); } if (method == ZipOutputStream.DEFLATED && avail > 0) { System.arraycopy(buf, len - avail, buf, 0, avail); len = avail; avail = 0; inf.setInput(buf, 0, len); } return entry; }