Home | History | Annotate | Download | only in pm
      1 package android.content.pm;
      2 
      3 import java.io.FilterInputStream;
      4 import java.io.IOException;
      5 import java.io.InputStream;
      6 import java.util.Arrays;
      7 
      8 /**
      9  * A class that limits the amount of data that is read from an InputStream. When
     10  * the specified length is reached, the stream returns an EOF even if the
     11  * underlying stream still has more data.
     12  *
     13  * @hide
     14  */
     15 public class LimitedLengthInputStream extends FilterInputStream {
     16     /**
     17      * The end of the stream where we don't want to allow more data to be read.
     18      */
     19     private final long mEnd;
     20 
     21     /**
     22      * Current offset in the stream.
     23      */
     24     private long mOffset;
     25 
     26     /**
     27      * @param in underlying stream to wrap
     28      * @param offset offset into stream where data starts
     29      * @param length length of data at offset
     30      * @throws IOException if an error occurred with the underlying stream
     31      */
     32     public LimitedLengthInputStream(InputStream in, long offset, long length) throws IOException {
     33         super(in);
     34 
     35         if (in == null) {
     36             throw new IOException("in == null");
     37         }
     38 
     39         if (offset < 0) {
     40             throw new IOException("offset < 0");
     41         }
     42 
     43         if (length < 0) {
     44             throw new IOException("length < 0");
     45         }
     46 
     47         if (length > Long.MAX_VALUE - offset) {
     48             throw new IOException("offset + length > Long.MAX_VALUE");
     49         }
     50 
     51         mEnd = offset + length;
     52 
     53         skip(offset);
     54         mOffset = offset;
     55     }
     56 
     57     @Override
     58     public synchronized int read() throws IOException {
     59         if (mOffset >= mEnd) {
     60             return -1;
     61         }
     62 
     63         mOffset++;
     64         return super.read();
     65     }
     66 
     67     @Override
     68     public int read(byte[] buffer, int offset, int byteCount) throws IOException {
     69         if (mOffset >= mEnd) {
     70             return -1;
     71         }
     72 
     73         final int arrayLength = buffer.length;
     74         Arrays.checkOffsetAndCount(arrayLength, offset, byteCount);
     75 
     76         if (mOffset > Long.MAX_VALUE - byteCount) {
     77             throw new IOException("offset out of bounds: " + mOffset + " + " + byteCount);
     78         }
     79 
     80         if (mOffset + byteCount > mEnd) {
     81             byteCount = (int) (mEnd - mOffset);
     82         }
     83 
     84         final int numRead = super.read(buffer, offset, byteCount);
     85         mOffset += numRead;
     86 
     87         return numRead;
     88     }
     89 
     90     @Override
     91     public int read(byte[] buffer) throws IOException {
     92         return read(buffer, 0, buffer.length);
     93     }
     94 }
     95