KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > vfs > SocketStream


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.vfs;
30
31 import java.io.IOException JavaDoc;
32 import java.io.InputStream JavaDoc;
33 import java.io.OutputStream JavaDoc;
34 import java.net.Socket JavaDoc;
35
36 /**
37  * Specialized stream to handle sockets.
38  *
39  * <p>Unlike VfsStream, when the read() throws and IOException or
40  * a SocketException, SocketStream will throw a ClientDisconnectException.
41  */

42 public class SocketStream extends StreamImpl {
43   private static byte []UNIX_NEWLINE = new byte[] { (byte) '\n' };
44
45   private Socket JavaDoc _s;
46   private InputStream JavaDoc _is;
47   private OutputStream JavaDoc _os;
48   private boolean _needsFlush;
49   private byte []_newline = UNIX_NEWLINE;
50
51   private boolean _throwReadInterrupts = false;
52   private int _socketTimeout;
53
54   private long _totalReadBytes;
55   private long _totalWriteBytes;
56
57   public SocketStream()
58   {
59   }
60
61   public SocketStream(Socket JavaDoc s)
62   {
63     init(s);
64   }
65
66   /**
67    * Initialize the SocketStream with a new Socket.
68    *
69    * @param s the new socket.
70    */

71   public void init(Socket JavaDoc s)
72   {
73     _s = s;
74     
75     _is = null;
76     _os = null;
77     _needsFlush = false;
78   }
79
80   /**
81    * Initialize the SocketStream with a new Socket.
82    *
83    * @param s the new socket.
84    */

85   public void init(InputStream JavaDoc is, OutputStream JavaDoc os)
86   {
87     _is = is;
88     _os = os;
89     _needsFlush = false;
90   }
91
92   /**
93    * If true, throws read interrupts instead of returning an end of
94    * fail. Defaults to false.
95    */

96   public void setThrowReadInterrupts(boolean allowThrow)
97   {
98     _throwReadInterrupts = allowThrow;
99   }
100
101   /**
102    * If true, throws read interrupts instead of returning an end of
103    * fail. Defaults to false.
104    */

105   public boolean getThrowReadInterrupts()
106   {
107     return _throwReadInterrupts;
108   }
109
110   public void setNewline(byte []newline)
111   {
112     _newline = newline;
113   }
114
115   public byte []getNewline()
116   {
117     return _newline;
118   }
119
120   /**
121    * Returns true since the socket stream can be read.
122    */

123   public boolean canRead()
124   {
125     return _is != null || _s != null;
126   }
127
128   /**
129    * Reads bytes from the socket.
130    *
131    * @param buf byte buffer receiving the bytes
132    * @param offset offset into the buffer
133    * @param length number of bytes to read
134    * @return number of bytes read or -1
135    * @exception throws ClientDisconnectException if the connection is dropped
136    */

137   public int read(byte []buf, int offset, int length) throws IOException JavaDoc
138   {
139     try {
140       if (_is == null) {
141         if (_s == null)
142           return -1;
143         
144         _is = _s.getInputStream();
145       }
146
147       int readLength = _is.read(buf, offset, length);
148
149       if (readLength >= 0)
150         _totalReadBytes += readLength;
151
152       return readLength;
153     } catch (IOException JavaDoc e) {
154       if (_throwReadInterrupts)
155         throw e;
156       
157       try {
158         close();
159       } catch (IOException JavaDoc e1) {
160       }
161
162       return -1;
163     }
164   }
165
166   /**
167    * Reads bytes from the socket.
168    *
169    * @param buf byte buffer receiving the bytes
170    * @param offset offset into the buffer
171    * @param length number of bytes to read
172    * @return number of bytes read or -1
173    * @exception throws ClientDisconnectException if the connection is dropped
174    */

175   public int readTimeout(byte []buf, int offset, int length, long timeout)
176     throws IOException JavaDoc
177   {
178     Socket JavaDoc s = _s;
179       
180     if (s == null)
181       return -1;
182
183     int oldTimeout = s.getSoTimeout();;
184
185     try {
186       s.setSoTimeout((int) timeout);
187
188       return read(buf, offset, length);
189     } finally {
190       s.setSoTimeout(oldTimeout);
191     }
192   }
193
194   /**
195    * Returns the number of bytes available to be read from the input stream.
196    */

197   public int getAvailable() throws IOException JavaDoc
198   {
199     if (_is == null) {
200       if (_s == null)
201         return -1;
202     
203       _is = _s.getInputStream();
204     }
205
206     return _is.available();
207   }
208
209   public boolean canWrite()
210   {
211     return _os != null || _s != null;
212   }
213
214   /**
215    * Writes bytes to the socket.
216    *
217    * @param buf byte buffer containing the bytes
218    * @param offset offset into the buffer
219    * @param length number of bytes to read
220    * @param isEnd if the write is at a close.
221    *
222    * @exception throws ClientDisconnectException if the connection is dropped
223    */

224   public void write(byte []buf, int offset, int length, boolean isEnd)
225     throws IOException JavaDoc
226   {
227     if (_os == null) {
228       if (_s == null)
229         return;
230       
231       _os = _s.getOutputStream();
232     }
233     
234     try {
235       _needsFlush = true;
236       _os.write(buf, offset, length);
237       _totalWriteBytes += length;
238     } catch (IOException JavaDoc e) {
239       try {
240         close();
241       } catch (IOException JavaDoc e1) {
242       }
243
244       throw ClientDisconnectException.create(e);
245     }
246   }
247
248   /**
249    * Flushes the socket.
250    */

251   public void flush() throws IOException JavaDoc
252   {
253     if (_os == null || ! _needsFlush)
254       return;
255
256     _needsFlush = false;
257     try {
258       _os.flush();
259     } catch (IOException JavaDoc e) {
260       try {
261         close();
262       } catch (IOException JavaDoc e1) {
263       }
264       
265       throw ClientDisconnectException.create(e);
266     }
267   }
268
269   public void resetTotalBytes()
270   {
271     _totalReadBytes = 0;
272     _totalWriteBytes = 0;
273   }
274
275   public long getTotalReadBytes()
276   {
277     return _totalReadBytes;
278   }
279
280   public long getTotalWriteBytes()
281   {
282     return _totalWriteBytes;
283   }
284
285   /**
286    * Closes the write half of the stream.
287    */

288   public void closeWrite() throws IOException JavaDoc
289   {
290     OutputStream JavaDoc os = _os;
291     _os = null;
292
293     // since the output stream is opened lazily, we might
294
// need to open it
295
if (_s != null)
296       _s.shutdownOutput();
297     /*
298     if (os != null)
299       os.close();
300     */

301   }
302
303   /**
304    * Closes the underlying sockets and socket streams.
305    */

306   public void close() throws IOException JavaDoc
307   {
308     Socket JavaDoc s = _s;
309     _s = null;
310
311     OutputStream JavaDoc os = _os;
312     _os = null;
313
314     InputStream JavaDoc is = _is;
315     _is = null;
316
317     try {
318       if (os != null)
319         os.close();
320       
321       if (is != null)
322         is.close();
323     } finally {
324       if (s != null)
325         s.close();
326     }
327   }
328 }
329
330
Popular Tags