KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > hessian > mux > MuxInputStream


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

48
49 package com.caucho.hessian.mux;
50
51 import java.io.IOException JavaDoc;
52 import java.io.InputStream JavaDoc;
53
54 /**
55  * Input stream to a specific channel.
56  */

57 public class MuxInputStream extends InputStream JavaDoc {
58   private MuxServer server;
59   protected InputStream JavaDoc is;
60   private int channel;
61   
62   private String JavaDoc url;
63   
64   private int chunkLength;
65
66   /**
67    * Null argument constructor.
68    */

69   public MuxInputStream()
70   {
71   }
72
73   /**
74    * Initialize the multiplexor with input and output streams.
75    */

76   protected void init(MuxServer server, int channel)
77     throws IOException JavaDoc
78   {
79     this.server = server;
80     this.channel = channel;
81
82     this.url = null;
83
84     chunkLength = 0;
85   }
86
87   /**
88    * Gets the raw input stream. Clients will normally not call
89    * this.
90    */

91   protected InputStream JavaDoc getInputStream()
92     throws IOException JavaDoc
93   {
94     if (is == null && server != null)
95       is = server.readChannel(channel);
96     
97     return is;
98   }
99
100   void setInputStream(InputStream JavaDoc is)
101   {
102     this.is = is;
103   }
104
105   /**
106    * Gets the channel of the connection.
107    */

108   public int getChannel()
109   {
110     return channel;
111   }
112
113   /**
114    * Returns the request's URL
115    */

116   public String JavaDoc getURL()
117   {
118     return url;
119   }
120
121   /**
122    * Writes a data byte to the output stream.
123    */

124   public int read()
125     throws IOException JavaDoc
126   {
127     if (chunkLength <= 0) {
128       readToData(false);
129
130       if (chunkLength <= 0)
131         return -1;
132     }
133     
134     chunkLength--;
135     return is.read();
136   }
137
138   /**
139    * Complete writing to the stream, closing the channel.
140    */

141   public void close()
142     throws IOException JavaDoc
143   {
144     skipToEnd();
145   }
146
147   /**
148    * Skips data until the end of the channel.
149    */

150   private void skipToEnd()
151     throws IOException JavaDoc
152   {
153     InputStream JavaDoc is = getInputStream();
154     
155     if (is == null)
156       return;
157
158     if (chunkLength > 0)
159       is.skip(chunkLength);
160
161     for (int tag = is.read(); tag >= 0; tag = is.read()) {
162       switch (tag) {
163       case 'Y':
164         server.freeReadLock();
165         this.is = is = server.readChannel(channel);
166         if (is == null) {
167           this.server = null;
168           return;
169         }
170         break;
171         
172       case 'Q':
173         server.freeReadLock();
174         this.is = null;
175         this.server = null;
176         return;
177
178       case -1:
179         server.freeReadLock();
180         this.is = null;
181         this.server = null;
182         return;
183         
184       default:
185         int length = (is.read() << 8) + is.read();
186         is.skip(length);
187         break;
188       }
189     }
190   }
191
192   /**
193    * Reads tags, until getting data.
194    */

195   void readToData(boolean returnOnYield)
196     throws IOException JavaDoc
197   {
198     InputStream JavaDoc is = getInputStream();
199     
200     if (is == null)
201       return;
202     
203     for (int tag = is.read(); tag >= 0; tag = is.read()) {
204       switch (tag) {
205       case 'Y':
206         server.freeReadLock();
207         if (returnOnYield)
208           return;
209         server.readChannel(channel);
210         break;
211         
212       case 'Q':
213         server.freeReadLock();
214         this.is = null;
215         this.server = null;
216         return;
217         
218       case 'U':
219         this.url = readUTF();
220         break;
221
222       case 'D':
223         chunkLength = (is.read() << 8) + is.read();
224         return;
225
226       default:
227         readTag(tag);
228         break;
229       }
230     }
231   }
232
233   /**
234    * Subclasses will extend this to read values.
235    */

236   protected void readTag(int tag)
237     throws IOException JavaDoc
238   {
239     int length = (is.read() << 8) + is.read();
240     is.skip(length);
241   }
242
243   /**
244    * Reads a UTF-8 string.
245    *
246    * @return the utf-8 encoded string
247    */

248   protected String JavaDoc readUTF()
249     throws IOException JavaDoc
250   {
251     int len = (is.read() << 8) + is.read();
252
253     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
254
255     while (len > 0) {
256       int d1 = is.read();
257
258       if (d1 < 0)
259         return sb.toString();
260       else if (d1 < 0x80) {
261         len--;
262         sb.append((char) d1);
263       }
264       else if ((d1 & 0xe0) == 0xc0) {
265         len -= 2;
266         sb.append(((d1 & 0x1f) << 6) + (is.read() & 0x3f));
267       }
268       else if ((d1 & 0xf0) == 0xe0) {
269         len -= 3;
270         sb.append(((d1 & 0x0f) << 12) +
271                   ((is.read() & 0x3f) << 6) +
272                   (is.read() & 0x3f));
273       }
274       else
275         throw new IOException JavaDoc("utf-8 encoding error");
276     }
277
278     return sb.toString();
279   }
280 }
281
Popular Tags