View Javadoc

1   /*
2    * Created on Apr 14, 2004
3    *
4    */
5   package org.neo.swarm.util.io;
6   
7   import java.io.IOException;
8   import java.io.OutputStream;
9   import java.nio.ByteBuffer;
10  
11  /***
12   * Provides a ByteBufferOutputStream interface for writing to a socket
13   *  @author navery
14   */
15  public class ByteBufferOutputStream extends OutputStream {
16  	
17  	StreamCallback callback;	
18  	ByteBuffer buffer;
19  	
20  	public ByteBufferOutputStream(ByteBuffer buffer, StreamCallback callback) {
21  	     this.buffer = buffer;
22  	     this.callback = callback;
23  	}
24  	
25  	/* (non-Javadoc)
26  	 * @see java.io.OutputStream#write(int)
27  	 */
28  	public void write(int b) throws IOException {
29  		checkBuffer(1);
30  		buffer.put((byte) b);
31  	}
32  	
33  	/* (non-Javadoc)
34  	 * @see java.io.OutputStream#write(byte[])
35  	 */
36  	public void write(byte[] data) throws IOException {
37  		int bytesLeft = data.length;
38  		int copyBytes;
39  		int pos = 0;
40  		while (bytesLeft > 0) {
41  			copyBytes = Math.min(buffer.remaining(), bytesLeft);
42  			checkBuffer(copyBytes);
43  			copyBytes = Math.min(buffer.remaining(), bytesLeft);			
44  			buffer.put(data, pos, copyBytes);
45  			pos += copyBytes;
46  			bytesLeft -= copyBytes;
47  		}
48  	}
49  
50  	/* 
51  	 * When non blocking this call may write 0 bytes.
52  	 * @see java.io.OutputStream#flush()
53  	 */
54  	public void flush() throws IOException {
55  		int bufferSize = this.buffer.position();
56  		this.buffer.flip();
57  		//this.buffer.rewind();
58  		//this.buffer.limit(bufferSize);
59  		int written;
60  		written = this.callback.execute(this.buffer, bufferSize);
61  
62  		if (written == 0) {
63  			while ((written = this.callback.execute(this.buffer, bufferSize)) == 0) {
64  			Thread.yield();
65  			try {
66  				Thread.sleep(50);
67  			} catch (InterruptedException e) {
68  				e.printStackTrace();
69  			}
70  		}
71  		}
72  		this.buffer.clear();		
73  	}
74  	/* (non-Javadoc)
75  	 * @see java.io.OutputStream#close()
76  	 */
77  	public void close() throws IOException {
78  		this.buffer.clear();
79  		this.callback.close();
80  	}
81  	
82  	private void checkBuffer(int sizeRequired)  throws IOException {
83  		if (buffer.remaining() <= sizeRequired && buffer.position() > 0) {
84  			flush();
85  		}
86  	}
87  }