/* * Internal constructor. Creates a new ZipEntry by reading the * Central Directory Entry (CDE) from "in", which must be positioned * at the CDE signature. * * On exit, "in" will be positioned at the start of the next entry * in the Central Directory. */ ZipEntry(byte[] cdeHdrBuf, InputStream cdStream) throws IOException { Streams.readFully(cdStream, cdeHdrBuf, 0, cdeHdrBuf.length); BufferIterator it = HeapBufferIterator.iterator(cdeHdrBuf, 0, cdeHdrBuf.length, ByteOrder.LITTLE_ENDIAN); int sig = it.readInt(); if (sig != CENSIG) { ZipFile.throwZipException("Central Directory Entry", sig); } it.seek(8); int gpbf = it.readShort() & 0xffff; if ((gpbf & ZipFile.GPBF_UNSUPPORTED_MASK) != 0) { throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf); } compressionMethod = it.readShort() & 0xffff; time = it.readShort() & 0xffff; modDate = it.readShort() & 0xffff; // These are 32-bit values in the file, but 64-bit fields in this object. crc = ((long) it.readInt()) & 0xffffffffL; compressedSize = ((long) it.readInt()) & 0xffffffffL; size = ((long) it.readInt()) & 0xffffffffL; nameLength = it.readShort() & 0xffff; int extraLength = it.readShort() & 0xffff; int commentByteCount = it.readShort() & 0xffff; // This is a 32-bit value in the file, but a 64-bit field in this object. it.seek(42); localHeaderRelOffset = ((long) it.readInt()) & 0xffffffffL; byte[] nameBytes = new byte[nameLength]; Streams.readFully(cdStream, nameBytes, 0, nameBytes.length); if (containsNulByte(nameBytes)) { throw new ZipException("Filename contains NUL byte: " + Arrays.toString(nameBytes)); } name = new String(nameBytes, 0, nameBytes.length, StandardCharsets.UTF_8); if (extraLength > 0) { extra = new byte[extraLength]; Streams.readFully(cdStream, extra, 0, extraLength); } // The RI has always assumed UTF-8. (If GPBF_UTF8_FLAG isn't set, the encoding is // actually IBM-437.) if (commentByteCount > 0) { byte[] commentBytes = new byte[commentByteCount]; Streams.readFully(cdStream, commentBytes, 0, commentByteCount); comment = new String(commentBytes, 0, commentBytes.length, StandardCharsets.UTF_8); } }
/** Copy a {@link Resources#openRawResource(int)} into {@link File} for testing purposes. */ private void stageFile(int rawId, File file) throws Exception { new File(file.getParent()).mkdirs(); InputStream in = null; OutputStream out = null; try { in = getContext().getResources().openRawResource(rawId); out = new FileOutputStream(file); Streams.copy(in, out); } finally { IoUtils.closeQuietly(in); IoUtils.closeQuietly(out); } }
public void write(int oneByte) throws IOException { Streams.writeSingleByte(this, oneByte); }
/** * Skip up to {@code byteCount} bytes of data on the underlying input stream. Any skipped bytes * are added to the running checksum value. * * @param byteCount the number of bytes to skip. * @throws IOException if this stream is closed or another I/O error occurs. * @return the number of bytes skipped. */ @Override public long skip(long byteCount) throws IOException { return Streams.skipByReading(this, byteCount); }