package com.koushikdutta.async; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.callback.WritableCallback; import java.nio.ByteBuffer; public class BufferedDataSink implements DataSink { DataSink mDataSink; public BufferedDataSink(DataSink datasink) { mDataSink = datasink; mDataSink.setWriteableCallback(new WritableCallback() { @Override public void onWriteable() { writePending(); } }); } public boolean isBuffering() { return mPendingWrites != null; } public DataSink getDataSink() { return mDataSink; } private void writePending() { // Log.i("NIO", "Writing to buffer..."); if (mPendingWrites != null) { mDataSink.write(mPendingWrites); if (mPendingWrites.remaining() == 0) { mPendingWrites = null; if (endPending) mDataSink.end(); if (closePending) mDataSink.close(); } } if (mPendingWrites == null && mWritable != null) mWritable.onWriteable(); } ByteBufferList mPendingWrites; @Override public void write(ByteBuffer bb) { if (mPendingWrites == null) mDataSink.write(bb); if (bb.remaining() > 0) { int toRead = Math.min(bb.remaining(), mMaxBuffer); if (toRead > 0) { if (mPendingWrites == null) mPendingWrites = new ByteBufferList(); byte[] bytes = new byte[toRead]; bb.get(bytes); mPendingWrites.add(ByteBuffer.wrap(bytes)); } } } @Override public void write(ByteBufferList bb) { write(bb, false); } protected void write(ByteBufferList bb, boolean ignoreBuffer) { if (mPendingWrites == null) mDataSink.write(bb); if (bb.remaining() > 0) { int toRead = Math.min(bb.remaining(), mMaxBuffer); if (ignoreBuffer) toRead = bb.remaining(); if (toRead > 0) { if (mPendingWrites == null) mPendingWrites = new ByteBufferList(); bb.get(mPendingWrites, toRead); } } } WritableCallback mWritable; @Override public void setWriteableCallback(WritableCallback handler) { mWritable = handler; } @Override public WritableCallback getWriteableCallback() { return mWritable; } public int remaining() { if (mPendingWrites == null) return 0; return mPendingWrites.remaining(); } int mMaxBuffer = Integer.MAX_VALUE; public int getMaxBuffer() { return mMaxBuffer; } public void setMaxBuffer(int maxBuffer) { assert maxBuffer >= 0; mMaxBuffer = maxBuffer; } @Override public boolean isOpen() { return !closePending && mDataSink.isOpen(); } boolean closePending; @Override public void close() { if (mPendingWrites != null) { closePending = true; return; } mDataSink.close(); } boolean endPending; @Override public void end() { if (mPendingWrites != null) { endPending = true; return; } mDataSink.end(); } @Override public void setClosedCallback(CompletedCallback handler) { mDataSink.setClosedCallback(handler); } @Override public CompletedCallback getClosedCallback() { return mDataSink.getClosedCallback(); } @Override public AsyncServer getServer() { return mDataSink.getServer(); } }