/** * Reads uncompressed data into an array of bytes. If <code>len</code> is not zero, the method * will block until some input can be decompressed; otherwise, no bytes are read and <code>0 * </code> is returned. * * @param b the buffer into which the data is read * @param off the start offset in the destination array <code>b</code> * @param len the maximum number of bytes read * @return the actual number of bytes read, or -1 if the end of the compressed input is reached or * a preset dictionary is needed * @exception NullPointerException If <code>b</code> is <code>null</code>. * @exception IndexOutOfBoundsException If <code>off</code> is negative, <code>len</code> is * negative, or <code>len</code> is greater than <code>b.length - off</code> * @exception ZipException if a ZIP format error has occurred * @exception IOException if an I/O error has occurred */ public int read(byte[] b, int off, int len) throws IOException { ensureOpen(); if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } try { int n; while ((n = inf.inflate(b, off, len)) == 0) { if (inf.finished() || inf.needsDictionary()) { reachEOF = true; return -1; } if (inf.needsInput()) { fill(); } } return n; } catch (DataFormatException e) { String s = e.getMessage(); throw new ZipException(s != null ? s : "Invalid ZLIB data format"); } }
/** * Fills input buffer with more data to decompress. * * @exception IOException if an I/O error has occurred */ protected void fill() throws IOException { ensureOpen(); len = in.read(buf, 0, buf.length); if (len == -1) { throw new EOFException("Unexpected end of ZLIB input stream"); } inf.setInput(buf, 0, len); }
/** * Returns 0 after EOF has been reached, otherwise always return 1. * * <p>Programs should not count on this method to return the actual number of bytes that could be * read without blocking. * * @return 1 before EOF and 0 after EOF. * @exception IOException if an I/O error occurs. */ public int available() throws IOException { ensureOpen(); if (reachEOF) { return 0; } else { return 1; } }
/** * Skips specified number of bytes of uncompressed data. * * @param n the number of bytes to skip * @return the actual number of bytes skipped. * @exception IOException if an I/O error has occurred * @exception IllegalArgumentException if {@code n < 0} */ public long skip(long n) throws IOException { if (n < 0) { throw new IllegalArgumentException("negative skip length"); } ensureOpen(); int max = (int) Math.min(n, Integer.MAX_VALUE); int total = 0; while (total < max) { int len = max - total; if (len > b.length) { len = b.length; } len = read(b, 0, len); if (len == -1) { reachEOF = true; break; } total += len; } return total; }
/** * Reads a byte of uncompressed data. This method will block until enough input is available for * decompression. * * @return the byte read, or -1 if end of compressed input is reached * @exception IOException if an I/O error has occurred */ public int read() throws IOException { ensureOpen(); return read(singleByteBuf, 0, 1) == -1 ? -1 : Byte.toUnsignedInt(singleByteBuf[0]); }