add limited input stream
[jSite2.git] / src / net / pterodactylus / util / io / LimitedInputStream.java
1 /**
2  * © 2008 INA Service GmbH
3  */
4 package net.pterodactylus.util.io;
5
6 import java.io.FilterInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9
10 /**
11  * A wrapper around an {@link InputStream} that only supplies a limit number of
12  * bytes from the underlying input stream.
13  * 
14  * @author <a href="mailto:dr@ina-germany.de">David Roden</a>
15  * @version $Id$
16  */
17 public class LimitedInputStream extends FilterInputStream {
18
19         /** The remaining number of bytes that can be read. */
20         private long remaining;
21
22         /**
23          * Creates a new LimitedInputStream that supplies at most
24          * <code>length</code> bytes from the given input stream.
25          * 
26          * @param inputStream
27          *            The input stream
28          * @param length
29          *            The number of bytes to read
30          */
31         public LimitedInputStream(InputStream inputStream, long length) {
32                 super(inputStream);
33                 remaining = length;
34         }
35
36         /**
37          * @see java.io.FilterInputStream#available()
38          */
39         @Override
40         public synchronized int available() throws IOException {
41                 return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining));
42         }
43
44         /**
45          * @see java.io.FilterInputStream#read()
46          */
47         @Override
48         public synchronized int read() throws IOException {
49                 int read = -1;
50                 if (remaining > 0) {
51                         read = super.read();
52                         remaining--;
53                 }
54                 return read;
55         }
56
57         /**
58          * @see java.io.FilterInputStream#read(byte[], int, int)
59          */
60         @Override
61         public synchronized int read(byte[] b, int off, int len) throws IOException {
62                 if (remaining == 0) {
63                         return -1;
64                 }
65                 int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE));
66                 int read = super.read(b, off, toCopy);
67                 remaining -= read;
68                 return read;
69         }
70
71         /**
72          * @see java.io.FilterInputStream#skip(long)
73          */
74         @Override
75         public synchronized long skip(long n) throws IOException {
76                 if (n < 0) {
77                         return 0;
78                 }
79                 long skipped = super.skip(Math.min(n, remaining));
80                 remaining -= skipped;
81                 return skipped;
82         }
83
84         /**
85          * {@inheritDoc}
86          * 
87          * This method does nothing, as {@link #mark(int)} and {@link #reset()} are
88          * not supported.
89          * 
90          * @see java.io.FilterInputStream#mark(int)
91          */
92         @Override
93         public void mark(int readlimit) {
94                 /* do nothing. */
95         }
96
97         /**
98          * {@inheritDoc}
99          * 
100          * @see java.io.FilterInputStream#markSupported()
101          * @return <code>false</code>
102          */
103         @Override
104         public boolean markSupported() {
105                 return false;
106         }
107
108         /**
109          * {@inheritDoc}
110          * 
111          * This method does nothing, as {@link #mark(int)} and {@link #reset()} are
112          * not supported.
113          * 
114          * @see java.io.FilterInputStream#reset()
115          */
116         @Override
117         public void reset() throws IOException {
118                 /* do nothing. */
119         }
120
121         /**
122          * Consumes the input stream, i.e. read all bytes until the limit is
123          * reached.
124          * 
125          * @throws IOException
126          *             if an I/O error occurs
127          */
128         public void consume() throws IOException {
129                 while (remaining > 0) {
130                         skip(remaining);
131                 }
132         }
133
134 }