Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
LimitedInputStream |
|
| 1.4285714285714286;1,429 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | package org.apache.commons.fileupload.util; | |
18 | ||
19 | import java.io.FilterInputStream; | |
20 | import java.io.IOException; | |
21 | import java.io.InputStream; | |
22 | ||
23 | /** | |
24 | * An input stream, which limits its data size. This stream is | |
25 | * used, if the content length is unknown. | |
26 | */ | |
27 | public abstract class LimitedInputStream extends FilterInputStream implements Closeable { | |
28 | ||
29 | /** | |
30 | * The maximum size of an item, in bytes. | |
31 | */ | |
32 | private final long sizeMax; | |
33 | ||
34 | /** | |
35 | * The current number of bytes. | |
36 | */ | |
37 | private long count; | |
38 | ||
39 | /** | |
40 | * Whether this stream is already closed. | |
41 | */ | |
42 | private boolean closed; | |
43 | ||
44 | /** | |
45 | * Creates a new instance. | |
46 | * | |
47 | * @param inputStream The input stream, which shall be limited. | |
48 | * @param pSizeMax The limit; no more than this number of bytes | |
49 | * shall be returned by the source stream. | |
50 | */ | |
51 | public LimitedInputStream(InputStream inputStream, long pSizeMax) { | |
52 | 5 | super(inputStream); |
53 | 5 | sizeMax = pSizeMax; |
54 | 5 | } |
55 | ||
56 | /** | |
57 | * Called to indicate, that the input streams limit has | |
58 | * been exceeded. | |
59 | * | |
60 | * @param pSizeMax The input streams limit, in bytes. | |
61 | * @param pCount The actual number of bytes. | |
62 | * @throws IOException The called method is expected | |
63 | * to raise an IOException. | |
64 | */ | |
65 | protected abstract void raiseError(long pSizeMax, long pCount) | |
66 | throws IOException; | |
67 | ||
68 | /** | |
69 | * Called to check, whether the input streams | |
70 | * limit is reached. | |
71 | * | |
72 | * @throws IOException The given limit is exceeded. | |
73 | */ | |
74 | private void checkLimit() throws IOException { | |
75 | 36 | if (count > sizeMax) { |
76 | 4 | raiseError(sizeMax, count); |
77 | } | |
78 | 32 | } |
79 | ||
80 | /** | |
81 | * Reads the next byte of data from this input stream. The value | |
82 | * byte is returned as an <code>int</code> in the range | |
83 | * <code>0</code> to <code>255</code>. If no byte is available | |
84 | * because the end of the stream has been reached, the value | |
85 | * <code>-1</code> is returned. This method blocks until input data | |
86 | * is available, the end of the stream is detected, or an exception | |
87 | * is thrown. | |
88 | * <p> | |
89 | * This method | |
90 | * simply performs <code>in.read()</code> and returns the result. | |
91 | * | |
92 | * @return the next byte of data, or <code>-1</code> if the end of the | |
93 | * stream is reached. | |
94 | * @throws IOException if an I/O error occurs. | |
95 | * @see java.io.FilterInputStream#in | |
96 | */ | |
97 | @Override | |
98 | public int read() throws IOException { | |
99 | 0 | int res = super.read(); |
100 | 0 | if (res != -1) { |
101 | 0 | count++; |
102 | 0 | checkLimit(); |
103 | } | |
104 | 0 | return res; |
105 | } | |
106 | ||
107 | /** | |
108 | * Reads up to <code>len</code> bytes of data from this input stream | |
109 | * into an array of bytes. If <code>len</code> is not zero, the method | |
110 | * blocks until some input is available; otherwise, no | |
111 | * bytes are read and <code>0</code> is returned. | |
112 | * <p> | |
113 | * This method simply performs <code>in.read(b, off, len)</code> | |
114 | * and returns the result. | |
115 | * | |
116 | * @param b the buffer into which the data is read. | |
117 | * @param off The start offset in the destination array | |
118 | * <code>b</code>. | |
119 | * @param len the maximum number of bytes read. | |
120 | * @return the total number of bytes read into the buffer, or | |
121 | * <code>-1</code> if there is no more data because the end of | |
122 | * the stream has been reached. | |
123 | * @throws NullPointerException If <code>b</code> is <code>null</code>. | |
124 | * @throws IndexOutOfBoundsException If <code>off</code> is negative, | |
125 | * <code>len</code> is negative, or <code>len</code> is greater than | |
126 | * <code>b.length - off</code> | |
127 | * @throws IOException if an I/O error occurs. | |
128 | * @see java.io.FilterInputStream#in | |
129 | */ | |
130 | @Override | |
131 | public int read(byte[] b, int off, int len) throws IOException { | |
132 | 38 | int res = super.read(b, off, len); |
133 | 38 | if (res > 0) { |
134 | 36 | count += res; |
135 | 36 | checkLimit(); |
136 | } | |
137 | 34 | return res; |
138 | } | |
139 | ||
140 | /** | |
141 | * Returns, whether this stream is already closed. | |
142 | * | |
143 | * @return True, if the stream is closed, otherwise false. | |
144 | * @throws IOException An I/O error occurred. | |
145 | */ | |
146 | public boolean isClosed() throws IOException { | |
147 | 4 | return closed; |
148 | } | |
149 | ||
150 | /** | |
151 | * Closes this input stream and releases any system resources | |
152 | * associated with the stream. | |
153 | * This | |
154 | * method simply performs <code>in.close()</code>. | |
155 | * | |
156 | * @throws IOException if an I/O error occurs. | |
157 | * @see java.io.FilterInputStream#in | |
158 | */ | |
159 | @Override | |
160 | public void close() throws IOException { | |
161 | 6 | closed = true; |
162 | 6 | super.close(); |
163 | 6 | } |
164 | ||
165 | } |