package org.limewire.nio.channel;
import java.io.EOFException;
import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
/**
* A simple channel that buffers data in a <code>ByteBuffer</code>.
*/
public abstract class AbstractBufferChannelWriter implements ChannelWriter {
/**
* The sink channel we write to & interest ourselves on.
*/
protected InterestWritableByteChannel channel;
protected ByteBuffer buffer;
protected volatile boolean shutdown;
public AbstractBufferChannelWriter(int bufferSize) {
buffer = ByteBuffer.allocate(bufferSize);
}
/** The channel we're writing to. */
public synchronized InterestWritableByteChannel getWriteChannel() {
return channel;
}
/** The channel we're writing to. */
public synchronized void setWriteChannel(InterestWritableByteChannel channel) {
this.channel = channel;
channel.interestWrite(this, true);
}
/**
* Adds <code>data</code> to the buffer and signals interest in writing to
* the channel.
*
* @throws IOException if the channel is already shutdown
* @throws BufferOverflowException if there is insufficient space in the buffer
*/
public synchronized void put(byte[] data) throws IOException {
if (shutdown) {
throw new EOFException();
}
buffer.put(data);
if(channel != null)
channel.interestWrite(this, true);
}
/**
* Writes as many messages as possible to the sink.
*/
public synchronized boolean handleWrite() throws IOException {
if(channel == null)
throw new IllegalStateException("writing with no source.");
buffer.flip();
while (buffer.hasRemaining() && channel.write(buffer) > 0)
;
boolean remaining = buffer.hasRemaining();
if (remaining) {
buffer.compact();
return true;
} else {
buffer.clear();
channel.interestWrite(this, false);
return false;
}
}
/**
* Does nothing.
*/
public void handleIOException(IOException iox) {
// ignore
}
public void shutdown() {
shutdown = true;
}
}