FilterInputStream.java revision f5597e626ecf7949d249dea08c1a2964d890ec11
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.io;
19
20/**
21 * Wraps an existing {@link InputStream} and performs some transformation on
22 * the input data while it is being read. Transformations can be anything from a
23 * simple byte-wise filtering input data to an on-the-fly compression or
24 * decompression of the underlying stream. Input streams that wrap another input
25 * stream and provide some additional functionality on top of it usually inherit
26 * from this class.
27 *
28 * @see FilterOutputStream
29 */
30public class FilterInputStream extends InputStream {
31
32    /**
33     * The source input stream that is filtered.
34     */
35    protected volatile InputStream in;
36
37    /**
38     * Constructs a new {@code FilterInputStream} with the specified input
39     * stream as source.
40     *
41     * @param in
42     *            the non-null InputStream to filter reads on.
43     */
44    protected FilterInputStream(InputStream in) {
45        super();
46        this.in = in;
47    }
48
49    /**
50     * Returns the number of bytes that are available before this stream will
51     * block.
52     *
53     * @return the number of bytes available before blocking.
54     * @throws IOException
55     *             if an error occurs in this stream.
56     */
57    @Override
58    public int available() throws IOException {
59        return in.available();
60    }
61
62    /**
63     * Closes this stream. This implementation closes the filtered stream.
64     *
65     * @throws IOException
66     *             if an error occurs while closing this stream.
67     */
68    @Override
69    public void close() throws IOException {
70        in.close();
71    }
72
73    /**
74     * Sets a mark position in this stream. The parameter {@code readlimit}
75     * indicates how many bytes can be read before the mark is invalidated.
76     * Sending {@code reset()} will reposition this stream back to the marked
77     * position, provided that {@code readlimit} has not been surpassed.
78     * <p>
79     * This implementation sets a mark in the filtered stream.
80     *
81     * @param readlimit
82     *            the number of bytes that can be read from this stream before
83     *            the mark is invalidated.
84     * @see #markSupported()
85     * @see #reset()
86     */
87    @Override
88    public synchronized void mark(int readlimit) {
89        in.mark(readlimit);
90    }
91
92    /**
93     * Indicates whether this stream supports {@code mark()} and {@code reset()}.
94     * This implementation returns whether or not the filtered stream supports
95     * marking.
96     *
97     * @return {@code true} if {@code mark()} and {@code reset()} are supported,
98     *         {@code false} otherwise.
99     * @see #mark(int)
100     * @see #reset()
101     * @see #skip(long)
102     */
103    @Override
104    public boolean markSupported() {
105        return in.markSupported();
106    }
107
108    /**
109     * Reads a single byte from the filtered stream and returns it as an integer
110     * in the range from 0 to 255. Returns -1 if the end of this stream has been
111     * reached.
112     *
113     * @return the byte read or -1 if the end of the filtered stream has been
114     *         reached.
115     * @throws IOException
116     *             if the stream is closed or another IOException occurs.
117     */
118    @Override
119    public int read() throws IOException {
120        return in.read();
121    }
122
123    /**
124     * Reads bytes from this stream and stores them in the byte array
125     * {@code buffer}. Returns the number of bytes actually read or -1 if no
126     * bytes were read and the end of this stream was encountered. This
127     * implementation reads bytes from the filtered stream.
128     *
129     * @param buffer
130     *            the byte array in which to store the read bytes.
131     * @return the number of bytes actually read or -1 if the end of the
132     *         filtered stream has been reached while reading.
133     * @throws IOException
134     *             if this stream is closed or another IOException occurs.
135     */
136    @Override
137    public int read(byte[] buffer) throws IOException {
138        return read(buffer, 0, buffer.length);
139    }
140
141    /**
142     * Reads at most {@code count} bytes from this stream and stores them in the
143     * byte array {@code buffer} starting at {@code offset}. Returns the number
144     * of bytes actually read or -1 if no bytes have been read and the end of
145     * this stream has been reached. This implementation reads bytes from the
146     * filtered stream.
147     *
148     * @param buffer
149     *            the byte array in which to store the bytes read.
150     * @param offset
151     *            the initial position in {@code buffer} to store the bytes
152     *            read from this stream.
153     * @param count
154     *            the maximum number of bytes to store in {@code buffer}.
155     * @return the number of bytes actually read or -1 if the end of the
156     *         filtered stream has been reached while reading.
157     * @throws IOException
158     *             if this stream is closed or another I/O error occurs.
159     */
160    @Override
161    public int read(byte[] buffer, int offset, int count) throws IOException {
162        return in.read(buffer, offset, count);
163    }
164
165    /**
166     * Resets this stream to the last marked location. This implementation
167     * resets the target stream.
168     *
169     * @throws IOException
170     *             if this stream is already closed, no mark has been set or the
171     *             mark is no longer valid because more than {@code readlimit}
172     *             bytes have been read since setting the mark.
173     * @see #mark(int)
174     * @see #markSupported()
175     */
176    @Override
177    public synchronized void reset() throws IOException {
178        in.reset();
179    }
180
181    /**
182     * Skips {@code count} number of bytes in this stream. Subsequent
183     * {@code read()}'s will not return these bytes unless {@code reset()} is
184     * used. This implementation skips {@code count} number of bytes in the
185     * filtered stream.
186     *
187     * @param count
188     *            the number of bytes to skip.
189     * @return the number of bytes actually skipped.
190     * @throws IOException
191     *             if this stream is closed or another IOException occurs.
192     * @see #mark(int)
193     * @see #reset()
194     */
195    @Override
196    public long skip(long count) throws IOException {
197        return in.skip(count);
198    }
199}
200