SizeLimitInputStream.java

  1. package gov.usgs.earthquake.util;

  2. import java.io.FilterInputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;

  5. /**
  6.  * Stream that only allows a certain number of bytes to be read.
  7.  *
  8.  * Current implementation only tracks read bytes, and ignores any mark or reset
  9.  * calls.
  10.  */
  11. public class SizeLimitInputStream extends FilterInputStream {

  12.     /** Maximum number of bytes to read. */
  13.     private long limit;
  14.     /** Number of bytes already read. */
  15.     private long read = 0L;

  16.     /**
  17.      * Construct a new SizeLimitInputStream.
  18.      *
  19.      * @param in
  20.      *            stream to limit.
  21.      * @param limit
  22.      *            maximum number of bytes allowed to read.
  23.      */
  24.     public SizeLimitInputStream(InputStream in, final long limit) {
  25.         super(in);
  26.         this.limit = limit;
  27.     }

  28.     /**
  29.      * Return number of bytes read.
  30.      * @return bytes read
  31.      */
  32.     public long getRead() {
  33.         return this.read;
  34.     }

  35.     /**
  36.      * Read one byte.
  37.      */
  38.     @Override
  39.     public int read() throws IOException {
  40.         int b = in.read();
  41.         if (b != -1) {
  42.             read++;
  43.             checkLimit();
  44.         }
  45.         return b;
  46.     }

  47.     /**
  48.      * Read into an array of bytes.
  49.      */
  50.     @Override
  51.     public int read(byte[] b) throws IOException {
  52.         return read(b, 0, b.length);
  53.     }

  54.     /**
  55.      * Read into an array of bytes.
  56.      */
  57.     @Override
  58.     public int read(byte[] b, int off, int len) throws IOException {
  59.         int total = in.read(b, off, len);
  60.         if (total != -1) {
  61.             read += total;
  62.             checkLimit();
  63.         }
  64.         return total;
  65.     }

  66.     /**
  67.      * Check how many bytes have been read.
  68.      *
  69.      * @throws IOException
  70.      *             if more bytes than the limit allows have been read.
  71.      */
  72.     protected void checkLimit() throws IOException {
  73.         if (limit > 0 && read > limit) {
  74.             throw new IOException("Read more than size limit (" + limit
  75.                     + ") bytes");
  76.         }
  77.     }

  78. }