1f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/*
2f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt *  contributor license agreements.  See the NOTICE file distributed with
4f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  this work for additional information regarding copyright ownership.
5f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  the License.  You may obtain a copy of the License at
8f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *
9f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *
11f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  See the License for the specific language governing permissions and
15f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *  limitations under the License.
16f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project */
17f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
18f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectpackage java.io;
19f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
20f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/**
21f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Wraps an existing {@link InputStream} and performs some transformation on
22f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * the input data while it is being read. Transformations can be anything from a
23f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * simple byte-wise filtering input data to an on-the-fly compression or
24f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * decompression of the underlying stream. Input streams that wrap another input
25f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * stream and provide some additional functionality on top of it usually inherit
26f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * from this class.
27f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *
28f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * @see FilterOutputStream
29f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project */
30f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectpublic class FilterInputStream extends InputStream {
31f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
32f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    /**
33a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * The source input stream that is filtered.
34f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project     */
35f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    protected volatile InputStream in;
36f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    /**
38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * Constructs a new {@code FilterInputStream} with the specified input
39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * stream as source.
40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *
41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * <p><strong>Warning:</strong> passing a null source creates an invalid
42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * {@code FilterInputStream}, that fails on every method that is not
43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * overridden. Subclasses should check for null in their constructors.
44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *
45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @param in the input stream to filter reads on.
46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     */
47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    protected FilterInputStream(InputStream in) {
48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        this.in = in;
49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    @Override
52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    public int available() throws IOException {
53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        return in.available();
54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    /**
57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * Closes this stream. This implementation closes the filtered stream.
58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *
59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @throws IOException
60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *             if an error occurs while closing this stream.
61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     */
62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    @Override
63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    public void close() throws IOException {
64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        in.close();
65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    /**
68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * Sets a mark position in this stream. The parameter {@code readlimit}
69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * indicates how many bytes can be read before the mark is invalidated.
70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * Sending {@code reset()} will reposition this stream back to the marked
71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * position, provided that {@code readlimit} has not been surpassed.
72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * <p>
73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * This implementation sets a mark in the filtered stream.
74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *
75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @param readlimit
76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *            the number of bytes that can be read from this stream before
77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *            the mark is invalidated.
78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @see #markSupported()
79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @see #reset()
80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     */
81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    @Override
82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    public synchronized void mark(int readlimit) {
83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        in.mark(readlimit);
84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
85a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt
86a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    /**
87a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * Indicates whether this stream supports {@code mark()} and {@code reset()}.
88a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * This implementation returns whether or not the filtered stream supports
89a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * marking.
90a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     *
91a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * @return {@code true} if {@code mark()} and {@code reset()} are supported,
92a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     *         {@code false} otherwise.
93a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * @see #mark(int)
94a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * @see #reset()
95a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * @see #skip(long)
96a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     */
97a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    @Override
98a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    public boolean markSupported() {
99a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt        return in.markSupported();
100a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    }
101a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt
102a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    /**
103a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * Reads a single byte from the filtered stream and returns it as an integer
104a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * in the range from 0 to 255. Returns -1 if the end of this stream has been
105a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * reached.
106a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     *
107a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * @return the byte read or -1 if the end of the filtered stream has been
108a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     *         reached.
109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @throws IOException
110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *             if the stream is closed or another IOException occurs.
111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     */
112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    @Override
113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    public int read() throws IOException {
114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        return in.read();
115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
117f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    @Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        return in.read(buffer, byteOffset, byteCount);
119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    /**
122e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * Resets this stream to the last marked location. This implementation
123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * resets the target stream.
124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *
125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @throws IOException
126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *             if this stream is already closed, no mark has been set or the
127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *             mark is no longer valid because more than {@code readlimit}
128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *             bytes have been read since setting the mark.
129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @see #mark(int)
130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @see #markSupported()
131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     */
132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    @Override
133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    public synchronized void reset() throws IOException {
134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        in.reset();
135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
137a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    /**
138a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * Skips {@code byteCount} bytes in this stream. Subsequent
139a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * calls to {@code read} will not return these bytes unless {@code reset} is
140a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * used. This implementation skips {@code byteCount} bytes in the
141a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * filtered stream.
142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *
143f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project     * @return the number of bytes actually skipped.
144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @throws IOException
145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     *             if this stream is closed or another IOException occurs.
146a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt     * @see #mark(int)
147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     * @see #reset()
148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt     */
149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    @Override
150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    public long skip(long byteCount) throws IOException {
151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        return in.skip(byteCount);
1520d3a47d979ac35a49b2a2da9e80e16bd37aab877repo sync    }
153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt