KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > http > nio > SocketChannelOutputStream


1 // ========================================================================
2
// $Id: SocketChannelOutputStream.java,v 1.4 2005/08/13 00:01:26 gregwilkins Exp $
3
// Copyright 2003-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.http.nio;
17
18 import java.io.IOException JavaDoc;
19 import java.io.OutputStream JavaDoc;
20 import java.nio.ByteBuffer JavaDoc;
21 import java.nio.channels.SelectionKey JavaDoc;
22 import java.nio.channels.Selector JavaDoc;
23 import java.nio.channels.SocketChannel JavaDoc;
24
25 import org.apache.commons.logging.Log;
26 import org.mortbay.log.LogFactory;
27 import org.mortbay.util.LogSupport;
28
29 /* ------------------------------------------------------------------------------- */
30 /**
31  * Blocking output stream on non-blocking SocketChannel. Makes the
32  * assumption that writes will rarely need to block.
33  * All writes flush to the channel, and no additional buffering is done.
34  * @version $Revision: 1.4 $
35  * @author gregw
36  */

37 public class SocketChannelOutputStream extends OutputStream JavaDoc
38 {
39     private static Log log= LogFactory.getLog(SocketChannelOutputStream.class);
40     
41     ByteBuffer JavaDoc _buffer;
42     ByteBuffer JavaDoc _flush;
43     SocketChannel JavaDoc _channel;
44     Selector JavaDoc _selector;
45     
46     /* ------------------------------------------------------------------------------- */
47     /** Constructor.
48      *
49      */

50     public SocketChannelOutputStream(SocketChannel JavaDoc channel,
51                                                                              int bufferSize)
52     {
53         _channel=channel;
54         _buffer=ByteBuffer.allocateDirect(bufferSize);
55     }
56
57     /* ------------------------------------------------------------------------------- */
58     /*
59      * @see java.io.OutputStream#write(int)
60      */

61     public void write(int b) throws IOException JavaDoc
62     {
63         _buffer.clear();
64         _buffer.put((byte)b);
65         _buffer.flip();
66         _flush=_buffer;
67         flushBuffer();
68     }
69
70     
71     /* ------------------------------------------------------------------------------- */
72     /*
73      * @see java.io.OutputStream#close()
74      */

75     public void close() throws IOException JavaDoc
76     {
77         _channel.close();
78     }
79
80     /* ------------------------------------------------------------------------------- */
81     /*
82      * @see java.io.OutputStream#flush()
83      */

84     public void flush() throws IOException JavaDoc
85     {
86     }
87
88     /* ------------------------------------------------------------------------------- */
89     /*
90      * @see java.io.OutputStream#write(byte[], int, int)
91      */

92     public void write(byte[] buf, int offset, int length) throws IOException JavaDoc
93     {
94         if (length>_buffer.capacity())
95             _flush=ByteBuffer.wrap(buf,offset,length);
96         else
97          {
98              _buffer.clear();
99              _buffer.put(buf,offset,length);
100              _buffer.flip();
101              _flush=_buffer;
102          }
103          flushBuffer();
104     }
105
106     /* ------------------------------------------------------------------------------- */
107     /*
108      * @see java.io.OutputStream#write(byte[])
109      */

110     public void write(byte[] buf) throws IOException JavaDoc
111     {
112         if (buf.length>_buffer.capacity())
113             _flush=ByteBuffer.wrap(buf);
114         else
115          {
116              _buffer.clear();
117              _buffer.put(buf);
118              _buffer.flip();
119              _flush=_buffer;
120          }
121          flushBuffer();
122     }
123
124
125     /* ------------------------------------------------------------------------------- */
126     private void flushBuffer() throws IOException JavaDoc
127     {
128         while (_flush.hasRemaining())
129         {
130             int len=_channel.write(_flush);
131             if (len<0)
132                 throw new IOException JavaDoc("EOF");
133             if (len==0)
134             {
135                 // write channel full. Try letting other threads have a go.
136
Thread.yield();
137                 len=_channel.write(_flush);
138                 if (len<0)
139                     throw new IOException JavaDoc("EOF");
140                 if (len==0)
141                 {
142                     // still full. need to block until it is writable.
143
if (_selector==null)
144                      {
145                             _selector=Selector.open();
146                             _channel.register(_selector,SelectionKey.OP_WRITE);
147                      }
148
149                      _selector.select();
150                 }
151             }
152         }
153     }
154
155     /* ------------------------------------------------------------------------------- */
156     public void destroy()
157     {
158         if (_selector!=null)
159         {
160             try{_selector.close();}
161             catch(IOException JavaDoc e){ LogSupport.ignore(log,e);}
162             _selector=null;
163             _buffer=null;
164             _flush=null;
165             _channel=null;
166         }
167     }
168 }
169
Popular Tags