11d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License.  You may obtain a copy of the License at
81d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
101d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.util.zip;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.EOFException;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FilterInputStream;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.archive.internal.nls.Messages;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class provides an implementation of {@code FilterInputStream} that
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * uncompresses data that was compressed using the <i>DEFLATE</i> algorithm
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (see <a href="http://www.gzip.org/algorithm.txt">specification</a>).
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Basically it wraps the {@code Inflater} class and takes care of the
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * buffering.
33407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson *
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see Inflater
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see DeflaterOutputStream
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class InflaterInputStream extends FilterInputStream {
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The inflater used for this stream.
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected Inflater inf;
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The input buffer used for decompression.
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected byte[] buf;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The length of the buffer.
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected int len;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    boolean closed;
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
567f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson    /**
577f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * True if this stream's last byte has been returned to the user. This
587f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * could be because the underlying stream has been exhausted, or if errors
597f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * were encountered while inflating that stream.
607f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     */
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    boolean eof;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static final int BUF_SIZE = 512;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
651d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson    int nativeEndBufSize = 0; // android-only
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This is the most basic constructor. You only need to pass the {@code
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * InputStream} from which the compressed data is to be read from. Default
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * settings for the {@code Inflater} and internal buffer are be used. In
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * particular the Inflater expects a ZLIB header from the input stream.
72407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param is
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the {@code InputStream} to read data from.
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public InflaterInputStream(InputStream is) {
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this(is, new Inflater(), BUF_SIZE);
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This constructor lets you pass a specifically initialized Inflater,
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for example one that expects no ZLIB header.
83407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param is
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the {@code InputStream} to read data from.
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inf
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the specific {@code Inflater} for uncompressing data.
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public InflaterInputStream(InputStream is, Inflater inf) {
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this(is, inf, BUF_SIZE);
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This constructor lets you specify both the {@code Inflater} as well as
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the internal buffer size to be used.
96407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param is
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the {@code InputStream} to read data from.
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inf
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the specific {@code Inflater} for uncompressing data.
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param bsize
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the size to be used for the internal buffer.
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public InflaterInputStream(InputStream is, Inflater inf, int bsize) {
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(is);
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (is == null || inf == null) {
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (bsize <= 0) {
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException();
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.inf = inf;
1131d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson        // BEGIN android-only
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (is instanceof ZipFile.RAFStream) {
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            nativeEndBufSize = bsize;
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            buf = new byte[bsize];
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1191d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson        // END android-only
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Reads a single byte of decompressed data.
124407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the byte read.
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an error occurs reading the byte.
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int read() throws IOException {
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] b = new byte[1];
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (read(b, 0, 1) == -1) {
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return -1;
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return b[0] & 0xff;
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Reads up to {@code nbytes} of decompressed data and stores it in
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code buffer} starting at {@code off}.
141407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param buffer
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the buffer to write data to.
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param off
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            offset in buffer to start writing.
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param nbytes
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            number of bytes to read.
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return Number of uncompressed bytes read
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an IOException occurs.
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int read(byte[] buffer, int off, int nbytes) throws IOException {
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* archive.1E=Stream is closed */
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (closed) {
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (null == buffer) {
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (off < 0 || nbytes < 0 || off + nbytes > buffer.length) {
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IndexOutOfBoundsException();
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (nbytes == 0) {
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1717f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson        if (eof) {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return -1;
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // avoid int overflow, check null buffer
1767f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson        if (off > buffer.length || nbytes < 0 || off < 0
1777f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                || buffer.length - off < nbytes) {
1787f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            throw new ArrayIndexOutOfBoundsException();
1797f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson        }
1807f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson
1817f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson        do {
1827f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            if (inf.needsInput()) {
1837f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                fill();
1847f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            }
1857f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            // Invariant: if reading returns -1 or throws, eof must be true.
1867f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            // It may also be true if the next read() should return -1.
1877f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            try {
1887f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                int result = inf.inflate(buffer, off, nbytes);
1897f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                eof = inf.finished();
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (result > 0) {
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return result;
1927f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                } else if (eof) {
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return -1;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (inf.needsDictionary()) {
1957f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                    eof = true;
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return -1;
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (len == -1) {
1987f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                    eof = true;
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new EOFException();
200407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                    // If result == 0, fill() and try again
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
2027f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            } catch (DataFormatException e) {
2037f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                eof = true;
2047f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                if (len == -1) {
2057f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                    throw new EOFException();
2067f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                }
2077f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson                throw (IOException) (new IOException().initCause(e));
2087f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson            }
2097f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson        } while (true);
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Fills the input buffer with data to be decompressed.
214407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an {@code IOException} occurs.
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void fill() throws IOException {
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (closed) {
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2221d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson        // BEGIN android-only
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (nativeEndBufSize > 0) {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ZipFile.RAFStream is = (ZipFile.RAFStream)in;
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            synchronized (is.mSharedRaf) {
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                long len = is.mLength - is.mOffset;
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (len > nativeEndBufSize) len = nativeEndBufSize;
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int cnt = inf.setFileInput(is.mSharedRaf.getFD(), is.mOffset, (int)nativeEndBufSize);
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                is.skip(cnt);
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((len = in.read(buf)) > 0) {
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                inf.setInput(buf, 0, len);
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2361d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson        // END android-only
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Skips up to n bytes of uncompressed data.
241407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param nbytes
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the number of bytes to skip.
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of uncompressed bytes skipped.
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an error occurs skipping.
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public long skip(long nbytes) throws IOException {
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (nbytes >= 0) {
251407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            if (buf == null) {
2521d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson                buf = new byte[(int)Math.min(nbytes, BUF_SIZE)];
253407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            }
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            long count = 0, rem = 0;
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            while (count < nbytes) {
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int x = read(buf, 0,
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        (rem = nbytes - count) > buf.length ? buf.length
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                : (int) rem);
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (x == -1) {
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return count;
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count += x;
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return count;
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new IllegalArgumentException();
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
2707f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * Returns 0 when when this stream has exhausted its input; and 1 otherwise.
2717f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * A result of 1 does not guarantee that further bytes can be returned,
2727f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * with or without blocking.
2737f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     *
2747f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * <p>Although consistent with the RI, this behavior is inconsistent with
2757f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * {@link InputStream#available()}, and violates the <a
2767f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov
2777f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * Substitution Principle</a>. This method should not be used.
278407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
2797f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     * @return 0 if no further bytes are available. Otherwise returns 1,
2807f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     *         which suggests (but does not guarantee) that additional bytes are
2817f331f3efb8c9c9879bf6b5154eaf2fdc849ab9bJesse Wilson     *         available.
282fcf8f879d9dded6eb38b8b79198dd6351262cc17Elliott Hughes     * @throws IOException if this stream is closed or an error occurs
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int available() throws IOException {
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (closed) {
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // archive.1E=Stream is closed
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (eof) {
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 1;
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Closes the input stream.
298407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             If an error occurs closing the input stream.
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void close() throws IOException {
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!closed) {
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            inf.end();
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            closed = true;
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            eof = true;
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            super.close();
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
311407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
313407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     * Marks the current position in the stream. This implementation overrides
314407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     * the super type implementation to do nothing at all.
315407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param readlimit
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            of no use.
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void mark(int readlimit) {
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // do nothing
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Reset the position of the stream to the last marked position. This
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * implementation overrides the supertype implementation and always throws
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * an {@link IOException IOException} when called.
328407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the method is called
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
333407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson    public void reset() throws IOException {
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new IOException();
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
336407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns whether the receiver implements {@code mark} semantics. This type
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * does not support {@code mark()}, so always responds {@code false}.
340407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return false, always
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean markSupported() {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
349