Mega Code Archive

 
Categories / Java / File Input Output
 

An limited-data-size input stream

/*  * Licensed to the Apache Software Foundation (ASF) under one or more  * contributor license agreements.  See the NOTICE file distributed with  * this work for additional information regarding copyright ownership.  * The ASF licenses this file to You under the Apache License, Version 2.0  * (the "License"); you may not use this file except in compliance with  * the License.  You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; /**  * An input stream, which limits its data size. This stream is  * used, if the content length is unknown.  */ public abstract class LimitedInputStream         extends FilterInputStream {     /**      * The maximum size of an item, in bytes.      */     private long sizeMax;     /**      * The current number of bytes.      */     private long count;     /**      * Whether this stream is already closed.      */     private boolean closed;     /**      * Creates a new instance.      * @param pIn The input stream, which shall be limited.      * @param pSizeMax The limit; no more than this number of bytes      *   shall be returned by the source stream.      */     public LimitedInputStream(InputStream pIn, long pSizeMax) {         super(pIn);         sizeMax = pSizeMax;     }     /**      * Called to indicate, that the input streams limit has      * been exceeded.      * @param pSizeMax The input streams limit, in bytes.      * @param pCount The actual number of bytes.      * @throws IOException The called method is expected      *   to raise an IOException.      */     protected abstract void raiseError(long pSizeMax, long pCount)             throws IOException;     /** Called to check, whether the input streams      * limit is reached.      * @throws IOException The given limit is exceeded.      */     private void checkLimit() throws IOException {         if (count > sizeMax) {             raiseError(sizeMax, count);         }     }     /**      * Reads the next byte of data from this input stream. The value      * byte is returned as an <code>int</code> in the range      * <code>0</code> to <code>255</code>. If no byte is available      * because the end of the stream has been reached, the value      * <code>-1</code> is returned. This method blocks until input data      * is available, the end of the stream is detected, or an exception      * is thrown.      * <p>      * This method      * simply performs <code>in.read()</code> and returns the result.      *      * @return     the next byte of data, or <code>-1</code> if the end of the      *             stream is reached.      * @exception  IOException  if an I/O error occurs.      * @see        java.io.FilterInputStream#in      */     public int read() throws IOException {         int res = super.read();         if (res != -1) {             count++;             checkLimit();         }         return res;     }     /**      * Reads up to <code>len</code> bytes of data from this input stream      * into an array of bytes. If <code>len</code> is not zero, the method      * blocks until some input is available; otherwise, no      * bytes are read and <code>0</code> is returned.      * <p>      * This method simply performs <code>in.read(b, off, len)</code>      * and returns the result.      *      * @param      b     the buffer into which the data is read.      * @param      off   The start offset in the destination array      *                   <code>b</code>.      * @param      len   the maximum number of bytes read.      * @return     the total number of bytes read into the buffer, or      *             <code>-1</code> if there is no more data because the end of      *             the stream has been reached.      * @exception  NullPointerException If <code>b</code> is <code>null</code>.      * @exception  IndexOutOfBoundsException If <code>off</code> is negative,      * <code>len</code> is negative, or <code>len</code> is greater than      * <code>b.length - off</code>      * @exception  IOException  if an I/O error occurs.      * @see        java.io.FilterInputStream#in      */     public int read(byte[] b, int off, int len) throws IOException {         int res = super.read(b, off, len);         if (res > 0) {             count += res;             checkLimit();         }         return res;     }     /**      * Returns, whether this stream is already closed.      * @return True, if the stream is closed, otherwise false.      * @throws IOException An I/O error occurred.      */     public boolean isClosed() throws IOException {         return closed;     }     /**      * Closes this input stream and releases any system resources      * associated with the stream.      * This      * method simply performs <code>in.close()</code>.      *      * @exception  IOException  if an I/O error occurs.      * @see        java.io.FilterInputStream#in      */     public void close() throws IOException {         closed = true;         super.close();     } }