KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > upload > BufferedMultipartInputStream


1 /*
2  * $Id: BufferedMultipartInputStream.java 54929 2004-10-16 16:38:42Z germuska $
3  *
4  * Copyright 1999-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 package org.apache.struts.upload;
20
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.ByteArrayOutputStream JavaDoc;
24
25 /**
26  * This class implements buffering for an InputStream as well as a
27  * readLine method. The purpose of this is to provide a reliable
28  * readLine() method.
29  *
30  * @deprecated Use the Commons FileUpload based multipart handler instead. This
31  * class will be removed after Struts 1.2.
32  */

33 public class BufferedMultipartInputStream extends InputStream JavaDoc {
34    
35     /**
36      * The underlying InputStream used by this class
37      */

38     protected InputStream JavaDoc inputStream;
39     
40     /**
41      * The byte array used to hold buffered data
42      */

43     protected byte[] buffer;
44     
45     /**
46      * The current offset we're at in the buffer's byte array
47      */

48     protected int bufferOffset = 0;
49     
50     /**
51      * The size of the byte array buffer
52      */

53     protected int bufferSize = 8192;
54     
55     /**
56      * The number of bytes read from the underlying InputStream that are
57      * in the buffer
58      */

59     protected int bufferLength = 0;
60     
61     /**
62      * The total number of bytes read so far
63      */

64     protected int totalLength = 0;
65     
66     /**
67      * The content length of the multipart data
68      */

69     protected long contentLength;
70     
71     /**
72      * The maximum allowed size for the multipart data, or -1 for an unlimited
73      * maximum file length
74      */

75     protected long maxSize = -1;
76     
77     /**
78      * Whether or not bytes up to the Content-Length have been read
79      */

80     protected boolean contentLengthMet = false;
81     
82     /**
83      * Whether or not bytes up to the maximum length have been read
84      */

85     protected boolean maxLengthMet = false;
86     
87     
88     /**
89      * Public constructor for this class, just wraps the InputStream
90      * given
91      * @param inputStream The underlying stream to read from
92      * @param bufferSize The size in bytes of the internal buffer
93      * @param contentLength The content length for this request
94      * @param maxSize The maximum size in bytes that this multipart
95      * request can be, or -1 for an unlimited length
96      */

97     public BufferedMultipartInputStream(InputStream JavaDoc inputStream,
98                                         int bufferSize,
99                                         long contentLength,
100                                         long maxSize) throws IOException JavaDoc {
101         this.inputStream = inputStream;
102         this.bufferSize = bufferSize;
103         this.contentLength = contentLength;
104         this.maxSize = maxSize;
105         
106         if ((maxSize != -1) && (maxSize < contentLength)) {
107             throw new MaxLengthExceededException(maxSize);
108         }
109         buffer = new byte[bufferSize];
110         fill();
111     }
112     
113     /**
114      * This method returns the number of available bytes left to read
115      * in the buffer before it has to be refilled
116      */

117     public int available() {
118         return bufferLength - bufferOffset;
119     }
120     
121     /**
122      * This method attempts to close the underlying InputStream
123      */

124     public void close() throws IOException JavaDoc {
125         inputStream.close();
126     }
127     
128     /**
129      * This method calls on the mark() method of the underlying InputStream
130      */

131     public void mark(int position) {
132         inputStream.mark(position);
133     }
134     
135     /**
136      * This method calls on the markSupported() method of the underlying InputStream
137      * @return Whether or not the underlying InputStream supports marking
138      */

139     public boolean markSupported() {
140         return inputStream.markSupported();
141     }
142     
143     /**
144      * @return true if the maximum length has been reached, false otherwise
145      */

146     public boolean maxLengthMet() {
147         return maxLengthMet;
148     }
149     
150     /**
151      * @return true if the content length has been reached, false otherwise
152      */

153     public boolean contentLengthMet() {
154         return contentLengthMet;
155     }
156     
157     /**
158      * This method returns the next byte in the buffer, and refills it if necessary.
159      * @return The next byte read in the buffer, or -1 if the end of the stream has
160      * been reached
161      */

162     public int read() throws IOException JavaDoc {
163         
164         if (maxLengthMet) {
165             throw new MaxLengthExceededException(maxSize);
166         }
167         if (contentLengthMet) {
168             throw new ContentLengthExceededException(contentLength);
169         }
170         if (buffer == null) {
171             return -1;
172         }
173         
174         if (bufferOffset < bufferLength) {
175             return (int)(char) buffer[bufferOffset++];
176         }
177         fill();
178         return read();
179     }
180     
181     /**
182      * This method populates the byte array <code>b</code> with data up to
183      * <code>b.length</code> bytes
184      */

185     public int read(byte[] b) throws IOException JavaDoc {
186         return read(b, 0, b.length);
187     }
188     
189     /**
190      * This method populates the byte array <code>b</code> with data up to
191      * <code>length</code> starting at b[offset]
192      */

193     public int read(byte[] b, int offset, int length) throws IOException JavaDoc {
194         
195         int count = 0;
196         int read = read();
197         if (read == -1) {
198             return -1;
199         }
200         
201         while ((read != -1) && (count < length)) {
202             b[offset] = (byte) read;
203             read = read();
204             count++;
205             offset++;
206         }
207         return count;
208     }
209     
210     /**
211      * This method reads into the byte array <code>b</code> until
212      * a newline ('\n') character is encountered or the number of bytes
213      * specified by <code>length</code> have been read
214      */

215     public int readLine(byte[] b, int offset, int length) throws IOException JavaDoc {
216         
217         int count = 0;
218         int read = read();
219         if (read == -1) {
220             return -1;
221         }
222         
223         while ((read != -1) && (count < length)) {
224             if (read == '\n')
225                 break;
226             b[offset] = (byte) read;
227             count++;
228             offset++;
229             read = read();
230         }
231         return count;
232     }
233
234     /**
235      * This method reads a line, regardless of length.
236      * @return A byte array representing the line.
237      */

238     public byte[] readLine() throws IOException JavaDoc {
239
240         int read = read();
241         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
242
243          // return null if there are no more bytes to read
244
if( -1 == read )
245             return null;
246
247         while ((read != -1) && (read != '\n')) {
248             baos.write(read);
249             read = read();
250         }
251
252         return baos.toByteArray();
253     }
254
255     /**
256      * This method makes a call to the reset() method of the underlying
257      * InputStream
258      */

259     public void reset() throws IOException JavaDoc {
260         inputStream.reset();
261     }
262
263     /**
264      * Fills the buffer with data from the underlying inputStream. If it can't
265      * fill the entire buffer in one read, it will read as many times as necessary
266      * to fill the buffer
267      */

268     protected void fill() throws IOException JavaDoc {
269
270         if ((bufferOffset > -1) && (bufferLength > -1)) {
271             int length = Math.min(bufferSize, (((int) contentLength+1) - totalLength));
272             if (length == 0) {
273                 contentLengthMet = true;
274             }
275             if ((maxSize > -1) && (length > 0)){
276                 length = Math.min(length, ((int) maxSize - totalLength));
277                 if (length == 0) {
278                     maxLengthMet = true;
279                 }
280             }
281
282             int bytesRead = -1;
283             if (length > 0) {
284                 bytesRead = inputStream.read(buffer, 0, length);
285             }
286             if (bytesRead == -1) {
287                 buffer = null;
288                 bufferOffset = -1;
289                 bufferLength = -1;
290             }
291             else {
292                 bufferLength = bytesRead;
293                 totalLength += bytesRead;
294                 bufferOffset = 0;
295             }
296         }
297     }
298 }
Popular Tags