add limited input stream
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 10 Apr 2008 16:40:13 +0000 (16:40 +0000)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 10 Apr 2008 16:40:13 +0000 (16:40 +0000)
git-svn-id: http://trooper/svn/projects/jSite/trunk@699 c3eda9e8-030b-0410-8277-bc7414b0a119

src/net/pterodactylus/util/io/LimitedInputStream.java [new file with mode: 0644]

diff --git a/src/net/pterodactylus/util/io/LimitedInputStream.java b/src/net/pterodactylus/util/io/LimitedInputStream.java
new file mode 100644 (file)
index 0000000..8e23f24
--- /dev/null
@@ -0,0 +1,134 @@
+/**
+ * © 2008 INA Service GmbH
+ */
+package net.pterodactylus.util.io;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A wrapper around an {@link InputStream} that only supplies a limit number of
+ * bytes from the underlying input stream.
+ * 
+ * @author <a href="mailto:dr@ina-germany.de">David Roden</a>
+ * @version $Id$
+ */
+public class LimitedInputStream extends FilterInputStream {
+
+       /** The remaining number of bytes that can be read. */
+       private long remaining;
+
+       /**
+        * Creates a new LimitedInputStream that supplies at most
+        * <code>length</code> bytes from the given input stream.
+        * 
+        * @param inputStream
+        *            The input stream
+        * @param length
+        *            The number of bytes to read
+        */
+       public LimitedInputStream(InputStream inputStream, long length) {
+               super(inputStream);
+               remaining = length;
+       }
+
+       /**
+        * @see java.io.FilterInputStream#available()
+        */
+       @Override
+       public synchronized int available() throws IOException {
+               return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining));
+       }
+
+       /**
+        * @see java.io.FilterInputStream#read()
+        */
+       @Override
+       public synchronized int read() throws IOException {
+               int read = -1;
+               if (remaining > 0) {
+                       read = super.read();
+                       remaining--;
+               }
+               return read;
+       }
+
+       /**
+        * @see java.io.FilterInputStream#read(byte[], int, int)
+        */
+       @Override
+       public synchronized int read(byte[] b, int off, int len) throws IOException {
+               if (remaining == 0) {
+                       return -1;
+               }
+               int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE));
+               int read = super.read(b, off, toCopy);
+               remaining -= read;
+               return read;
+       }
+
+       /**
+        * @see java.io.FilterInputStream#skip(long)
+        */
+       @Override
+       public synchronized long skip(long n) throws IOException {
+               if (n < 0) {
+                       return 0;
+               }
+               long skipped = super.skip(Math.min(n, remaining));
+               remaining -= skipped;
+               return skipped;
+       }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * This method does nothing, as {@link #mark(int)} and {@link #reset()} are
+        * not supported.
+        * 
+        * @see java.io.FilterInputStream#mark(int)
+        */
+       @Override
+       public void mark(int readlimit) {
+               /* do nothing. */
+       }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @see java.io.FilterInputStream#markSupported()
+        * @return <code>false</code>
+        */
+       @Override
+       public boolean markSupported() {
+               return false;
+       }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * This method does nothing, as {@link #mark(int)} and {@link #reset()} are
+        * not supported.
+        * 
+        * @see java.io.FilterInputStream#reset()
+        */
+       @Override
+       public void reset() throws IOException {
+               /* do nothing. */
+       }
+
+       /**
+        * Consumes the input stream, i.e. read all bytes until the limit is
+        * reached.
+        * 
+        * @throws IOException
+        *             if an I/O error occurs
+        */
+       public void consume() throws IOException {
+               while (remaining > 0) {
+                       skip(remaining);
+               }
+       }
+
+}