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