InflaterInputStream.java revision f9480f317cddcec859025833b748f096247a40aa
1f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License.  You may obtain a copy of the License at
8f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.zip;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.EOFException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FilterInputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
24b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughesimport java.util.Arrays;
253541c79d5058b86e742867b4ee5811a1de01de1fJesse Wilsonimport libcore.base.Streams;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class provides an implementation of {@code FilterInputStream} that
298cfafd33742282beb20c6971aafc1feb35e3fa5eJesse Wilson * decompresses data that was compressed using the <i>DEFLATE</i> algorithm
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (see <a href="http://www.gzip.org/algorithm.txt">specification</a>).
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Basically it wraps the {@code Inflater} class and takes care of the
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffering.
3357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson *
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Inflater
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see DeflaterOutputStream
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class InflaterInputStream extends FilterInputStream {
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The inflater used for this stream.
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Inflater inf;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The input buffer used for decompression.
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected byte[] buf;
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The length of the buffer.
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected int len;
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    boolean closed;
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
560146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson    /**
570146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * True if this stream's last byte has been returned to the user. This
580146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * could be because the underlying stream has been exhausted, or if errors
590146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * were encountered while inflating that stream.
600146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     */
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    boolean eof;
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static final int BUF_SIZE = 512;
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
65f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson    int nativeEndBufSize = 0; // android-only
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This is the most basic constructor. You only need to pass the {@code
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * InputStream} from which the compressed data is to be read from. Default
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * settings for the {@code Inflater} and internal buffer are be used. In
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * particular the Inflater expects a ZLIB header from the input stream.
7257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param is
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code InputStream} to read data from.
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InflaterInputStream(InputStream is) {
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(is, new Inflater(), BUF_SIZE);
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This constructor lets you pass a specifically initialized Inflater,
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for example one that expects no ZLIB header.
8357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param is
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code InputStream} to read data from.
86018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson     * @param inflater
878cfafd33742282beb20c6971aafc1feb35e3fa5eJesse Wilson     *            the specific {@code Inflater} for decompressing data.
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
89018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    public InflaterInputStream(InputStream is, Inflater inflater) {
90018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        this(is, inflater, BUF_SIZE);
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This constructor lets you specify both the {@code Inflater} as well as
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the internal buffer size to be used.
9657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param is
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code InputStream} to read data from.
99018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson     * @param inflater
1008cfafd33742282beb20c6971aafc1feb35e3fa5eJesse Wilson     *            the specific {@code Inflater} for decompressing data.
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bsize
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the size to be used for the internal buffer.
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
104018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    public InflaterInputStream(InputStream is, Inflater inflater, int bsize) {
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(is);
106018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        if (is == null || inflater == null) {
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (bsize <= 0) {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
112018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        this.inf = inflater;
113f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson        // BEGIN android-only
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (is instanceof ZipFile.RAFStream) {
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            nativeEndBufSize = bsize;
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            buf = new byte[bsize];
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
119f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson        // END android-only
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads a single byte of decompressed data.
12457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte read.
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs reading the byte.
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int read() throws IOException {
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] b = new byte[1];
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (read(b, 0, 1) == -1) {
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return b[0] & 0xff;
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
139b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes     * Reads up to {@code byteCount} bytes of decompressed data and stores it in
140b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes     * {@code buffer} starting at {@code offset}.
14157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return Number of uncompressed bytes read
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
145b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes    public int read(byte[] buffer, int offset, int byteCount) throws IOException {
14660eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes        checkClosed();
147b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes        Arrays.checkOffsetAndCount(buffer.length, offset, byteCount);
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
149b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes        if (byteCount == 0) {
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1530146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        if (eof) {
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1570146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        do {
1580146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            if (inf.needsInput()) {
1590146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                fill();
1600146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            }
1610146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            // Invariant: if reading returns -1 or throws, eof must be true.
1620146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            // It may also be true if the next read() should return -1.
1630146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            try {
164b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes                int result = inf.inflate(buffer, offset, byteCount);
1650146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                eof = inf.finished();
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (result > 0) {
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return result;
1680146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                } else if (eof) {
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return -1;
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (inf.needsDictionary()) {
1710146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                    eof = true;
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return -1;
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (len == -1) {
1740146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                    eof = true;
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new EOFException();
17657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    // If result == 0, fill() and try again
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1780146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            } catch (DataFormatException e) {
1790146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                eof = true;
1800146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                if (len == -1) {
1810146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                    throw new EOFException();
1820146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                }
1830146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                throw (IOException) (new IOException().initCause(e));
1840146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            }
1850146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        } while (true);
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Fills the input buffer with data to be decompressed.
19057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an {@code IOException} occurs.
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void fill() throws IOException {
19560eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes        checkClosed();
196f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson        // BEGIN android-only
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nativeEndBufSize > 0) {
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ZipFile.RAFStream is = (ZipFile.RAFStream)in;
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            synchronized (is.mSharedRaf) {
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                long len = is.mLength - is.mOffset;
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (len > nativeEndBufSize) len = nativeEndBufSize;
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int cnt = inf.setFileInput(is.mSharedRaf.getFD(), is.mOffset, (int)nativeEndBufSize);
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                is.skip(cnt);
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((len = in.read(buf)) > 0) {
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                inf.setInput(buf, 0, len);
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
210f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson        // END android-only
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2143541c79d5058b86e742867b4ee5811a1de01de1fJesse Wilson     * Skips up to {@code byteCount} bytes of uncompressed data.
21557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
2163541c79d5058b86e742867b4ee5811a1de01de1fJesse Wilson     * @param byteCount the number of bytes to skip.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of uncompressed bytes skipped.
218f9480f317cddcec859025833b748f096247a40aaElliott Hughes     * @throws IllegalArgumentException if {@code byteCount < 0}.
2193541c79d5058b86e742867b4ee5811a1de01de1fJesse Wilson     * @throws IOException if an error occurs skipping.
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
2223541c79d5058b86e742867b4ee5811a1de01de1fJesse Wilson    public long skip(long byteCount) throws IOException {
223f9480f317cddcec859025833b748f096247a40aaElliott Hughes        if (byteCount < 0) {
224f9480f317cddcec859025833b748f096247a40aaElliott Hughes            throw new IllegalArgumentException("byteCount < 0");
225f9480f317cddcec859025833b748f096247a40aaElliott Hughes        }
2263541c79d5058b86e742867b4ee5811a1de01de1fJesse Wilson        return Streams.skipByReading(this, byteCount);
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2300146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * Returns 0 when when this stream has exhausted its input; and 1 otherwise.
2310146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * A result of 1 does not guarantee that further bytes can be returned,
2320146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * with or without blocking.
2330146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     *
2340146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * <p>Although consistent with the RI, this behavior is inconsistent with
2350146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * {@link InputStream#available()}, and violates the <a
2360146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov
2370146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * Substitution Principle</a>. This method should not be used.
23857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
2390146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * @return 0 if no further bytes are available. Otherwise returns 1,
2400146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     *         which suggests (but does not guarantee) that additional bytes are
2410146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     *         available.
242582d926fbf5f5fd4800def67f86ecfedee44681eElliott Hughes     * @throws IOException if this stream is closed or an error occurs
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int available() throws IOException {
24660eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes        checkClosed();
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (eof) {
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return 1;
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the input stream.
25557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an error occurs closing the input stream.
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!closed) {
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            inf.end();
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            closed = true;
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            eof = true;
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.close();
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
26857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
27057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     * Marks the current position in the stream. This implementation overrides
27157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     * the super type implementation to do nothing at all.
27257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param readlimit
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            of no use.
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void mark(int readlimit) {
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // do nothing
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reset the position of the stream to the last marked position. This
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation overrides the supertype implementation and always throws
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an {@link IOException IOException} when called.
28557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the method is called
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
29057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson    public void reset() throws IOException {
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new IOException();
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
29357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the receiver implements {@code mark} semantics. This type
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * does not support {@code mark()}, so always responds {@code false}.
29757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return false, always
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean markSupported() {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
30560eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes    private void checkClosed() throws IOException {
30660eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes        if (closed) {
30760eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes            throw new IOException("Stream is closed");
30860eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes        }
30960eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes    }
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
311