1 16 package org.mortbay.http.nio; 17 18 import java.io.IOException ; 19 import java.io.OutputStream ; 20 import java.nio.ByteBuffer ; 21 import java.nio.channels.SelectionKey ; 22 import java.nio.channels.Selector ; 23 import java.nio.channels.SocketChannel ; 24 25 import org.apache.commons.logging.Log; 26 import org.mortbay.log.LogFactory; 27 import org.mortbay.util.LogSupport; 28 29 30 37 public class SocketChannelOutputStream extends OutputStream 38 { 39 private static Log log= LogFactory.getLog(SocketChannelOutputStream.class); 40 41 ByteBuffer _buffer; 42 ByteBuffer _flush; 43 SocketChannel _channel; 44 Selector _selector; 45 46 47 50 public SocketChannelOutputStream(SocketChannel channel, 51 int bufferSize) 52 { 53 _channel=channel; 54 _buffer=ByteBuffer.allocateDirect(bufferSize); 55 } 56 57 58 61 public void write(int b) throws IOException 62 { 63 _buffer.clear(); 64 _buffer.put((byte)b); 65 _buffer.flip(); 66 _flush=_buffer; 67 flushBuffer(); 68 } 69 70 71 72 75 public void close() throws IOException 76 { 77 _channel.close(); 78 } 79 80 81 84 public void flush() throws IOException 85 { 86 } 87 88 89 92 public void write(byte[] buf, int offset, int length) throws IOException 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 110 public void write(byte[] buf) throws IOException 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 127 { 128 while (_flush.hasRemaining()) 129 { 130 int len=_channel.write(_flush); 131 if (len<0) 132 throw new IOException ("EOF"); 133 if (len==0) 134 { 135 Thread.yield(); 137 len=_channel.write(_flush); 138 if (len<0) 139 throw new IOException ("EOF"); 140 if (len==0) 141 { 142 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 e){ LogSupport.ignore(log,e);} 162 _selector=null; 163 _buffer=null; 164 _flush=null; 165 _channel=null; 166 } 167 } 168 } 169 | Popular Tags |