KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > transport > http > NonBlockingBufferedInputStream


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55
56 package org.jboss.axis.transport.http;
57
58 import java.io.IOException JavaDoc;
59 import java.io.InputStream JavaDoc;
60
61 public class NonBlockingBufferedInputStream extends InputStream JavaDoc
62 {
63
64    // current stream to be processed
65
private InputStream JavaDoc in;
66
67    // maximum number of bytes allowed to be returned.
68
private int remainingContent = Integer.MAX_VALUE;
69
70    // Internal buffer for the input stream
71
private byte[] buffer = new byte[4096];
72    private int offset = 0; // bytes before this offset have been processed
73
private int numbytes = 0; // number of valid bytes in this buffer
74

75    /**
76     * set the input stream to be used for subsequent reads
77     *
78     * @param in the InputStream
79     */

80    public void setInputStream(InputStream JavaDoc in)
81    {
82       this.in = in;
83       numbytes = 0;
84       offset = 0;
85       remainingContent = (in == null) ? 0 : Integer.MAX_VALUE;
86    }
87
88    /**
89     * set the maximum number of bytes allowed to be read from this input
90     * stream.
91     *
92     * @param value the Content Length
93     */

94    public void setContentLength(int value)
95    {
96       if (in != null) this.remainingContent = value - (numbytes - offset);
97    }
98
99    /**
100     * Replenish the buffer with data from the input stream. This is
101     * guaranteed to read atleast one byte or throw an exception. When
102     * possible, it will read up to the length of the buffer
103     * the data is buffered for efficiency.
104     *
105     * @return the byte read
106     */

107    private void refillBuffer() throws IOException JavaDoc
108    {
109       if (remainingContent <= 0 || in == null) return;
110
111       // determine number of bytes to read
112
numbytes = in.available();
113       if (numbytes > remainingContent) numbytes = remainingContent;
114       if (numbytes > buffer.length) numbytes = buffer.length;
115       if (numbytes <= 0) numbytes = 1;
116
117       // actually attempt to read those bytes
118
numbytes = in.read(buffer, 0, numbytes);
119
120       // update internal state to reflect this read
121
remainingContent -= numbytes;
122       offset = 0;
123    }
124
125    /**
126     * Read a byte from the input stream, blocking if necessary. Internally
127     * the data is buffered for efficiency.
128     *
129     * @return the byte read
130     */

131    public int read() throws IOException JavaDoc
132    {
133       if (in == null) return -1;
134       if (offset >= numbytes) refillBuffer();
135       if (offset >= numbytes) return -1;
136       return buffer[offset++];
137    }
138
139    /**
140     * Read bytes from the input stream. This is guaranteed to return at
141     * least one byte or throw an exception. When possible, it will return
142     * more bytes, up to the length of the array, as long as doing so would
143     * not require waiting on bytes from the input stream.
144     *
145     * @param dest byte array to read into
146     * @return the number of bytes actually read
147     */

148    public int read(byte[] dest) throws IOException JavaDoc
149    {
150       return read(dest, 0, dest.length);
151    }
152
153    /**
154     * Read a specified number of bytes from the input stream. This is
155     * guaranteed to return at least one byte or throw an execption. When
156     * possible, it will return more bytes, up to the length specified,
157     * as long as doing so would not require waiting on bytes from the
158     * input stream.
159     *
160     * @param dest byte array to read into
161     * @param off starting offset into the byte array
162     * @param len maximum number of bytes to read
163     * @return the number of bytes actually read
164     */

165    public int read(byte[] dest, int off, int len) throws IOException JavaDoc
166    {
167       int ready = numbytes - offset;
168
169       if (ready >= len)
170       {
171          System.arraycopy(buffer, offset, dest, off, len);
172          offset += len;
173          return len;
174       }
175       else if (ready > 0)
176       {
177          System.arraycopy(buffer, offset, dest, off, ready);
178          offset = numbytes;
179          return ready;
180       }
181       else
182       {
183          if (in == null) return -1;
184          refillBuffer();
185          if (offset >= numbytes) return -1;
186          return read(dest, off, len);
187       }
188    }
189
190    /**
191     * skip over (and discard) a specified number of bytes in this input
192     * stream
193     *
194     * @param len the number of bytes to be skipped
195     * @return the action number of bytes skipped
196     */

197    public int skip(int len) throws IOException JavaDoc
198    {
199       int count = 0;
200       while (len-- > 0 && read() >= 0) count++;
201       return count;
202    }
203
204    /**
205     * return the number of bytes available to be read without blocking
206     *
207     * @return the number of bytes
208     */

209    public int available() throws IOException JavaDoc
210    {
211       if (in == null) return 0;
212
213       // return buffered + available from the stream
214
return (numbytes - offset) + in.available();
215    }
216
217    /**
218     * disassociate from the underlying input stream
219     */

220    public void close() throws IOException JavaDoc
221    {
222       setInputStream(null);
223    }
224
225    /**
226     * Just like read except byte is not removed from the buffer.
227     * the data is buffered for efficiency.
228     * Was added to support multiline http headers. ;-)
229     *
230     * @return the byte read
231     */

232    public int peek() throws IOException JavaDoc
233    {
234       if (in == null) return -1;
235       if (offset >= numbytes) refillBuffer();
236       if (offset >= numbytes) return -1;
237       return buffer[offset];
238    }
239 }
240
241
Popular Tags