package com.limegroup.gnutella.connection; import java.io.IOException; import java.nio.ByteBuffer; import com.limegroup.gnutella.io.ChannelWriter; import com.limegroup.gnutella.io.InterestWriteChannel; import com.limegroup.gnutella.io.WriteObserver; public class WriteBufferChannel implements ChannelWriter, InterestWriteChannel { private ByteBuffer buffer; private boolean closed = false; public InterestWriteChannel channel; public WriteObserver observer; public boolean status; private boolean shutdown; public WriteBufferChannel(int size) { buffer = ByteBuffer.allocate(size); } public WriteBufferChannel(ByteBuffer buffer, InterestWriteChannel channel) { this.buffer = buffer; this.channel = channel; channel.interest(this, true); } public WriteBufferChannel(byte[] data, InterestWriteChannel channel) { this(ByteBuffer.wrap(data), channel); } public WriteBufferChannel(byte[] data, int off, int len, InterestWriteChannel channel) { this(ByteBuffer.wrap(data, off, len), channel); } public WriteBufferChannel() { this(0); } public WriteBufferChannel(InterestWriteChannel channel) { this(ByteBuffer.allocate(0), channel); } public int write(ByteBuffer source) throws IOException { int wrote = 0; if(buffer.hasRemaining()) { int remaining = buffer.remaining(); int adding = source.remaining(); if(remaining >= adding) { buffer.put(source); wrote = adding; } else { int oldLimit = source.limit(); int position = source.position(); source.limit(position + remaining); buffer.put(source); source.limit(oldLimit); wrote = remaining; } } return wrote; } public boolean isOpen() { return !closed; } public void close() throws IOException { closed = true; } public void setClosed(boolean closed) { this.closed = closed; } public int written() { return buffer.position(); } public int remaining() { return buffer.remaining(); } public ByteBuffer getBuffer() { return (ByteBuffer)buffer.flip(); } public String getDataAsString() { ByteBuffer buffer = getBuffer(); return new String(buffer.array(), 0, buffer.limit()); } public void setBuffer(ByteBuffer buffer) { this.buffer = buffer; channel.interest(this, true); } public void resize(int size) { buffer = ByteBuffer.allocate(size); } public void clear() { buffer.clear(); } public boolean interested() { return status; } public void setWriteChannel(InterestWriteChannel chan) { channel = chan; } public InterestWriteChannel getWriteChannel() { return channel; } public void interest(WriteObserver observer, boolean status) { this.observer = observer; this.status = status; } public boolean handleWrite() throws IOException { while(buffer.hasRemaining() && channel.write(buffer) > 0); if(!buffer.hasRemaining()) channel.interest(this, false); return buffer.hasRemaining(); } public void shutdown() { shutdown = true; } public void handleIOException(IOException iox) { throw (RuntimeException)new UnsupportedOperationException("not implemented").initCause(iox); } public int position() { return buffer.position(); } public int limit() { return buffer.limit(); } public boolean isShutdown() { return shutdown; } }