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