KickJava   Java API By Example, From Geeks To Geeks.

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


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

16
17 package org.apache.axis.transport.http;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21
22 public class NonBlockingBufferedInputStream extends InputStream JavaDoc {
23
24     // current stream to be processed
25
private InputStream JavaDoc in;
26
27     // maximum number of bytes allowed to be returned.
28
private int remainingContent = Integer.MAX_VALUE;
29
30     // Internal buffer for the input stream
31
private byte[] buffer = new byte[4096];
32     private int offset = 0; // bytes before this offset have been processed
33
private int numbytes = 0; // number of valid bytes in this buffer
34

35     /**
36      * set the input stream to be used for subsequent reads
37      * @param in the InputStream
38      */

39     public void setInputStream (InputStream JavaDoc in) {
40         this.in = in;
41         numbytes = 0;
42         offset = 0;
43         remainingContent = (in==null)? 0 : Integer.MAX_VALUE;
44     }
45
46     /**
47      * set the maximum number of bytes allowed to be read from this input
48      * stream.
49      * @param value the Content Length
50      */

51     public void setContentLength (int value) {
52         if (in != null) this.remainingContent = value - (numbytes-offset);
53     }
54
55     /**
56      * Replenish the buffer with data from the input stream. This is
57      * guaranteed to read atleast one byte or throw an exception. When
58      * possible, it will read up to the length of the buffer
59      * the data is buffered for efficiency.
60      * @return the byte read
61      */

62     private void refillBuffer() throws IOException JavaDoc {
63         if (remainingContent <= 0 || in == null) return;
64
65         // determine number of bytes to read
66
numbytes = in.available();
67         if (numbytes > remainingContent) numbytes=remainingContent;
68         if (numbytes > buffer.length) numbytes=buffer.length;
69         if (numbytes <= 0) numbytes = 1;
70
71         // actually attempt to read those bytes
72
numbytes = in.read(buffer, 0, numbytes);
73
74         // update internal state to reflect this read
75
remainingContent -= numbytes;
76         offset = 0;
77     }
78
79     /**
80      * Read a byte from the input stream, blocking if necessary. Internally
81      * the data is buffered for efficiency.
82      * @return the byte read
83      */

84     public int read() throws IOException JavaDoc {
85         if (in == null) return -1;
86         if (offset >= numbytes) refillBuffer();
87         if (offset >= numbytes) return -1;
88         return buffer[offset++] & 0xFF;
89     }
90     
91     /**
92      * Read bytes from the input stream. This is guaranteed to return at
93      * least one byte or throw an exception. When possible, it will return
94      * more bytes, up to the length of the array, as long as doing so would
95      * not require waiting on bytes from the input stream.
96      * @param dest byte array to read into
97      * @return the number of bytes actually read
98      */

99     public int read(byte[] dest) throws IOException JavaDoc {
100         return read(dest, 0, dest.length);
101     }
102
103     /**
104      * Read a specified number of bytes from the input stream. This is
105      * guaranteed to return at least one byte or throw an execption. When
106      * possible, it will return more bytes, up to the length specified,
107      * as long as doing so would not require waiting on bytes from the
108      * input stream.
109      * @param dest byte array to read into
110      * @param off starting offset into the byte array
111      * @param len maximum number of bytes to read
112      * @return the number of bytes actually read
113      */

114     public int read(byte[] dest, int off, int len) throws IOException JavaDoc {
115         int ready = numbytes - offset;
116
117         if (ready >= len) {
118             System.arraycopy(buffer, offset, dest, off, len);
119             offset += len;
120             return len;
121         } else if (ready>0) {
122             System.arraycopy(buffer, offset, dest, off, ready);
123             offset = numbytes;
124             return ready;
125         } else {
126             if (in == null) return -1;
127             refillBuffer();
128             if (offset >= numbytes) return -1;
129             return read(dest,off,len);
130         }
131     }
132     
133     /**
134      * skip over (and discard) a specified number of bytes in this input
135      * stream
136      * @param len the number of bytes to be skipped
137      * @return the action number of bytes skipped
138      */

139     public int skip(int len) throws IOException JavaDoc {
140         int count = 0;
141         while (len-->0 && read()>=0) count++;
142         return count;
143     }
144
145     /**
146      * return the number of bytes available to be read without blocking
147      * @return the number of bytes
148      */

149     public int available() throws IOException JavaDoc {
150         if (in == null) return 0;
151
152         // return buffered + available from the stream
153
return (numbytes-offset) + in.available();
154     }
155
156     /**
157      * disassociate from the underlying input stream
158      */

159     public void close() throws IOException JavaDoc {
160         setInputStream(null);
161     }
162
163     /**
164      * Just like read except byte is not removed from the buffer.
165      * the data is buffered for efficiency.
166      * Was added to support multiline http headers. ;-)
167      * @return the byte read
168      */

169     public int peek() throws IOException JavaDoc {
170         if (in == null) return -1;
171         if (offset >= numbytes) refillBuffer();
172         if (offset >= numbytes) return -1;
173         return buffer[offset] & 0xFF;
174     }
175 }
176
177
Popular Tags