InflaterInputStream.java revision f7c6911047d63bc76292f55ce538da32818dd931
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;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.archive.internal.nls.Messages;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class provides an implementation of {@code FilterInputStream} that
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * uncompresses 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.
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param inf
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific {@code Inflater} for uncompressing data.
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InflaterInputStream(InputStream is, Inflater inf) {
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(is, inf, 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.
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param inf
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific {@code Inflater} for uncompressing 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     */
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InflaterInputStream(InputStream is, Inflater inf, int bsize) {
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(is);
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (is == null || inf == 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        }
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.inf = inf;
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    /**
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reads up to {@code nbytes} of decompressed data and stores it in
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code buffer} starting at {@code off}.
14157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buffer
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer to write data to.
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param off
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            offset in buffer to start writing.
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param nbytes
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            number of bytes to read.
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return Number of uncompressed bytes read
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an IOException occurs.
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int read(byte[] buffer, int off, int nbytes) throws IOException {
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /* archive.1E=Stream is closed */
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (closed) {
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (null == buffer) {
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (off < 0 || nbytes < 0 || off + nbytes > buffer.length) {
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nbytes == 0) {
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1710146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        if (eof) {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // avoid int overflow, check null buffer
1760146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        if (off > buffer.length || nbytes < 0 || off < 0
1770146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                || buffer.length - off < nbytes) {
1780146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            throw new ArrayIndexOutOfBoundsException();
1790146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        }
1800146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson
1810146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        do {
1820146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            if (inf.needsInput()) {
1830146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                fill();
1840146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            }
1850146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            // Invariant: if reading returns -1 or throws, eof must be true.
1860146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            // It may also be true if the next read() should return -1.
1870146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            try {
1880146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                int result = inf.inflate(buffer, off, nbytes);
1890146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                eof = inf.finished();
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (result > 0) {
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return result;
1920146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                } else if (eof) {
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return -1;
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (inf.needsDictionary()) {
1950146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                    eof = true;
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return -1;
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (len == -1) {
1980146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                    eof = true;
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new EOFException();
20057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    // If result == 0, fill() and try again
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2020146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            } catch (DataFormatException e) {
2030146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                eof = true;
2040146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                if (len == -1) {
2050146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                    throw new EOFException();
2060146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                }
2070146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson                throw (IOException) (new IOException().initCause(e));
2080146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson            }
2090146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson        } while (true);
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Fills the input buffer with data to be decompressed.
21457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an {@code IOException} occurs.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void fill() throws IOException {
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (closed) {
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
222f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson        // BEGIN android-only
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nativeEndBufSize > 0) {
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ZipFile.RAFStream is = (ZipFile.RAFStream)in;
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            synchronized (is.mSharedRaf) {
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                long len = is.mLength - is.mOffset;
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (len > nativeEndBufSize) len = nativeEndBufSize;
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int cnt = inf.setFileInput(is.mSharedRaf.getFD(), is.mOffset, (int)nativeEndBufSize);
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                is.skip(cnt);
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((len = in.read(buf)) > 0) {
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                inf.setInput(buf, 0, len);
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
236f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson        // END android-only
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Skips up to n bytes of uncompressed data.
24157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param nbytes
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes to skip.
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of uncompressed bytes skipped.
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs skipping.
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long skip(long nbytes) throws IOException {
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nbytes >= 0) {
25157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            if (buf == null) {
252f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson                buf = new byte[(int)Math.min(nbytes, BUF_SIZE)];
25357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            }
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long count = 0, rem = 0;
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (count < nbytes) {
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int x = read(buf, 0,
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        (rem = nbytes - count) > buf.length ? buf.length
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : (int) rem);
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (x == -1) {
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return count;
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                count += x;
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return count;
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new IllegalArgumentException();
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2700146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * Returns 0 when when this stream has exhausted its input; and 1 otherwise.
2710146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * A result of 1 does not guarantee that further bytes can be returned,
2720146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * with or without blocking.
2730146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     *
2740146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * <p>Although consistent with the RI, this behavior is inconsistent with
2750146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * {@link InputStream#available()}, and violates the <a
2760146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov
2770146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * Substitution Principle</a>. This method should not be used.
27857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
2790146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     * @return 0 if no further bytes are available. Otherwise returns 1,
2800146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     *         which suggests (but does not guarantee) that additional bytes are
2810146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson     *         available.
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an error occurs.
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int available() throws IOException {
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (closed) {
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // archive.1E=Stream is closed
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (eof) {
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return 1;
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the input stream.
29957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If an error occurs closing the input stream.
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!closed) {
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            inf.end();
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            closed = true;
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            eof = true;
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.close();
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
31257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
31457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     * Marks the current position in the stream. This implementation overrides
31557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     * the super type implementation to do nothing at all.
31657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param readlimit
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            of no use.
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void mark(int readlimit) {
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // do nothing
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Reset the position of the stream to the last marked position. This
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation overrides the supertype implementation and always throws
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an {@link IOException IOException} when called.
32957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the method is called
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
33457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson    public void reset() throws IOException {
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new IOException();
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
33757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the receiver implements {@code mark} semantics. This type
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * does not support {@code mark()}, so always responds {@code false}.
34157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return false, always
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean markSupported() {
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
350