151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.zip; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FilterInputStream; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.InputStream; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Implements an input stream filter for compressing data in the "deflate" 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * compression format. 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.6 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author David R Tribble (david@tribble.com) 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see DeflaterOutputStream 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see InflaterOutputStream 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see InflaterInputStream 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class DeflaterInputStream extends FilterInputStream { 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Compressor for this stream. */ 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected final Deflater def; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Input buffer for reading compressed data. */ 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected final byte[] buf; 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Temporary read buffer. */ 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] rbuf = new byte[1]; 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Default compressor is used. */ 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean usesDefaultDeflater = false; 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** End of the underlying input stream has been reached. */ 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean reachEOF = false; 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Check to make sure that this stream has not been closed. 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void ensureOpen() throws IOException { 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (in == null) { 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Stream closed"); 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new input stream with a default compressor and buffer 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * size. 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in input stream to read the uncompressed data to 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if {@code in} is null 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DeflaterInputStream(InputStream in) { 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(in, new Deflater()); 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski usesDefaultDeflater = true; 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new input stream with the specified compressor and a 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * default buffer size. 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in input stream to read the uncompressed data to 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param defl compressor ("deflater") for this stream 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if {@code in} or {@code defl} is null 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DeflaterInputStream(InputStream in, Deflater defl) { 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(in, defl, 512); 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new input stream with the specified compressor and buffer 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * size. 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in input stream to read the uncompressed data to 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param defl compressor ("deflater") for this stream 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param bufLen compression buffer size 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if {@code bufLen} is <= 0 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws NullPointerException if {@code in} or {@code defl} is null 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DeflaterInputStream(InputStream in, Deflater defl, int bufLen) { 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(in); 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Sanity checks 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (in == null) 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("Null input"); 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (defl == null) 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("Null deflater"); 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bufLen < 1) 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Buffer size < 1"); 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Initialize 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski def = defl; 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buf = new byte[bufLen]; 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Closes this input stream and its underlying input stream, discarding 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * any pending uncompressed data. 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() throws IOException { 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (in != null) { 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Clean up 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (usesDefaultDeflater) { 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski def.end(); 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in.close(); 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in = null; 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a single byte of compressed data from the input stream. 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method will block until some input can be read and compressed. 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a single byte of compressed data, or -1 if the end of the 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * uncompressed input stream is reached 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs or if this stream is 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * already closed 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read() throws IOException { 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Read a single byte of compressed data 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = read(rbuf, 0, 1); 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len <= 0) 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (rbuf[0] & 0xFF); 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads compressed data into a byte array. 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method will block until some input can be read and compressed. 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param b buffer into which the data is read 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param off starting offset of the data within {@code b} 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param len maximum number of compressed bytes to read into {@code b} 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the actual number of bytes read, or -1 if the end of the 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * uncompressed input stream is reached 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IndexOutOfBoundsException if {@code len} > {@code b.length - 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * off} 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs or if this input stream is 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * already closed 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(byte[] b, int off, int len) throws IOException { 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Sanity checks 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (b == null) { 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("Null buffer for read"); 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (off < 0 || len < 0 || len > b.length - off) { 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (len == 0) { 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Read and compress (deflate) input data bytes 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int cnt = 0; 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (len > 0 && !def.finished()) { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Read data from the input stream 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (def.needsInput()) { 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = in.read(buf, 0, buf.length); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n < 0) { 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // End of the input stream reached 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski def.finish(); 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (n > 0) { 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski def.setInput(buf, 0, n); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Compress the input data, filling the read buffer 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = def.deflate(b, off, len); 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cnt += n; 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski off += n; 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len -= n; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 205457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath 206457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath // Android changed : set reachEOF eagerly (not just when the number of bytes is zero). 207457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath // so that available is more accurate. 208457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath if (def.finished()) { 209457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath reachEOF =true; 210457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath if (cnt == 0) { 211457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath cnt = -1; 212457d3b26a6cbd62d203d3b56f69bcc441ea8d66fNarayan Kamath } 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cnt; 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Skips over and discards data from the input stream. 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method may block until the specified number of bytes are read and 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * skipped. <em>Note:</em> While {@code n} is given as a {@code long}, 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the maximum number of bytes which can be skipped is 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code Integer.MAX_VALUE}. 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param n number of bytes to be skipped 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the actual number of bytes skipped 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs or if this stream is 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * already closed 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long skip(long n) throws IOException { 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n < 0) { 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("negative skip length"); 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Skip bytes by repeatedly decompressing small blocks 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rbuf.length < 512) 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rbuf = new byte[512]; 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int total = (int)Math.min(n, Integer.MAX_VALUE); 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long cnt = 0; 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (total > 0) { 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Read a small block of uncompressed bytes 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = read(rbuf, 0, (total <= rbuf.length ? total : rbuf.length)); 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len < 0) { 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cnt += len; 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski total -= len; 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cnt; 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns 0 after EOF has been reached, otherwise always return 1. 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Programs should not count on this method to return the actual number 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of bytes that could be read without blocking 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return zero after the end of the underlying input stream has been 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reached, otherwise always returns 1 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error occurs or if this stream is 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * already closed 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int available() throws IOException { 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (reachEOF) { 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 1; 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Always returns {@code false} because this input stream does not support 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the {@link #mark mark()} and {@link #reset reset()} methods. 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return false, always 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean markSupported() { 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>This operation is not supported</i>. 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param limit maximum bytes that can be read before invalidating the position marker 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void mark(int limit) { 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Operation not supported 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>This operation is not supported</i>. 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException always thrown 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void reset() throws IOException { 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("mark/reset not supported"); 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 301