KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > net > server > WorkerInputStream


1 package com.quadcap.net.server;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.FileOutputStream JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.InputStream JavaDoc;
44
45 import com.quadcap.util.Debug;
46 import com.quadcap.util.Util;
47
48 /**
49  * An efficient worker input stream, which supports recycling.
50  * Additionally, this class performs all necessary buffering and
51  * some other higher level functions on the socket input stream, so
52  * no extra 'buffered' are needed.
53  *
54  * <p>In a violoation of layering, but to achieve maximum performance,
55  * this class knows how to "parse" HTTP headers.</p>
56  *
57  * @author Stan Bailes
58  */

59 public final class WorkerInputStream extends InputStream JavaDoc {
60     final static int MAX = 4096;
61     byte[] buf = new byte[MAX+1];
62     int pos = 0;
63     int lim = 0;
64     boolean eof = false;
65     InputStream JavaDoc in;
66
67     //#ifdef DEBUG
68
static boolean doTrace = false;
69     FileOutputStream JavaDoc log;
70     //#endif
71

72
73     public WorkerInputStream(FileOutputStream JavaDoc f) {
74         //#ifdef DEBUG
75
doTrace = (f != null);
76         log = f;
77         //#endif
78
}
79
80     public final void reset(InputStream JavaDoc in) throws IOException JavaDoc {
81         this.in = in;
82         this.eof = false;
83         this.pos = 0;
84         this.lim = 0;
85         //#ifdef DEBUG
86
if (doTrace) {
87             log.write(("RESET " + Thread.currentThread().getName() +
88                        "\r\n").getBytes());
89         }
90         //#endif
91
}
92
93     public final int read() throws IOException JavaDoc {
94         if (pos >= lim && !eof) fill();
95         int c = eof ? -1 : buf[pos++];
96         return c;
97     }
98
99     public void unread(int c) {
100         buf[--pos] = (byte)c;
101     }
102
103     /**
104      * Fill the buffer. Return true unless we're at end of file and have
105      * returned zero bytes in this fill
106      */

107     final boolean fill() throws IOException JavaDoc {
108         boolean ret = true;
109         pos = 0;
110         lim = in.read(buf, 0, MAX);
111         if (lim < 0) {
112             eof = true;
113             lim = 0;
114             ret = false;
115         }
116         //#ifdef DEBUG
117
if (doTrace) log.write(buf, 0, lim);
118         //#endif
119
return ret;
120     }
121
122     public final int read(byte[] b, int off, int len) throws IOException JavaDoc {
123         int rlim = off + len;
124         while (off < rlim && !eof) {
125             if (pos >= lim) fill();
126             int cnt = lim - pos;
127             if (len < cnt) cnt = len;
128             if (cnt > 0) {
129                 System.arraycopy(buf, pos, b, off, cnt);
130                 pos += cnt;
131                 off += cnt;
132             }
133         }
134         int cnt = off - (rlim - len);
135         return cnt == 0 ? (eof ? -1 : 0) : cnt;
136     }
137
138     public final int read(byte[] b) throws IOException JavaDoc {
139         return read(b, 0, b.length);
140     }
141
142     static byte[] CRLF = { 0x0d, 0x0a, 0x0d, 0x0a };
143
144     /**
145      * Read HTTP readers from the input stream.
146      * @param hbuf We place the entire header octet sequence into hbuf,
147      * terminated with CRLF
148      * @param offsets We place the byte offset of the start of each
149      * header into the offsets array
150      * @return the number of headers found
151      */

152     public final int readHeaders(byte[] hbuf, int[] offsets)
153         throws IOException JavaDoc
154     {
155         int off = 0; // offset into hbuf
156
int p = pos;
157         int l = lim;
158         int hcnt = 1;
159         buf[lim] = (byte)'\r';
160         int s = 1;
161         while (true) {
162             while (buf[p++] != '\r') continue;
163             while (l - p < 4 - s) {
164                 if (p > l) {
165                     p--;
166                     s--;
167                 }
168                 while (p < l && buf[p++] == CRLF[s]) {
169                     if (++s == 2 && off + p - pos > 2) {
170                         offsets[hcnt++] = p - pos + off;
171                     }
172                 }
173                 int len = p - pos;
174                 System.arraycopy(buf, pos, hbuf, off, len);
175                 fill();
176                 if (eof) {
177                     offsets[0] = hcnt - 1;
178                     return off + len;
179                 }
180                 p = 0;
181                 l = lim;
182                 buf[lim] = (byte)'\r';
183                 off += len;
184             }
185             while (buf[p++] == CRLF[s]) {
186                 ++s;
187                 final int len = p - pos;
188                 if (s == 2 && len+off > 2) {
189                     offsets[hcnt++] = len + off;
190                 } else if (s == 4) {
191                     System.arraycopy(buf, pos, hbuf, off, len);
192                     pos = p;
193                     offsets[0] = hcnt - 1;
194                     return off + len;
195                 }
196             }
197             s = 1;
198         }
199     }
200
201     final void show(String JavaDoc s, int p) {
202         System.out.println("------ " + s);
203         for (int i = 0; i < lim; i++) {
204             if (buf[i] == '\r') System.out.print('D');
205             else if (buf[i] == '\n') System.out.print('A');
206             else System.out.print((char)buf[i]);
207         }
208         System.out.println("");
209         for (int i = 0; i < p; i++) {
210             System.out.print(" ");
211         }
212         System.out.println("^");
213         System.out.println("");
214     }
215     
216     public final void close() throws IOException JavaDoc {
217         in.close();
218         in = null;
219         //#ifdef DEBUG
220
if (doTrace) log.write("CLOSE\r\n".getBytes());
221         //#endif
222
}
223
224     public String JavaDoc toString() {
225         return Util.strBytes(buf, 0, lim);
226     }
227
228 }
229
Popular Tags