org.testifyproject.github.dockerjava.netty.handler.HttpResponseStreamHandler Maven / Gradle / Ivy
package org.testifyproject.testifyproject.github.dockerjava.netty.handler;
import org.testifyproject.testifyproject.netty.buffer.ByteBuf;
import org.testifyproject.testifyproject.netty.channel.ChannelHandlerContext;
import org.testifyproject.testifyproject.netty.channel.SimpleChannelInboundHandler;
import java.org.testifyproject.testifyproject.IOException;
import java.org.testifyproject.testifyproject.InputStream;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.testifyproject.testifyproject.github.dockerjava.api.async.ResultCallback;
/**
* Handler that converts an incoming byte stream to an {@link InputStream}.
*
* @author marcus
*/
public class HttpResponseStreamHandler extends SimpleChannelInboundHandler {
private HttpResponseInputStream stream = new HttpResponseInputStream();
public HttpResponseStreamHandler(ResultCallback resultCallback) {
resultCallback.onNext(stream);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
stream.write(msg.copy());
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
stream.close();
super.channelReadComplete(ctx);
}
public static class HttpResponseInputStream extends InputStream {
private AtomicBoolean closed = new AtomicBoolean(false);
private LinkedTransferQueue queue = new LinkedTransferQueue();
private ByteBuf current = null;
public void write(ByteBuf byteBuf) {
queue.put(byteBuf);
}
@Override
public void close() throws IOException {
closed.set(true);
super.close();
}
@Override
public int available() throws IOException {
poll();
return readableBytes();
}
private int readableBytes() {
if (current != null) {
return current.readableBytes();
} else {
return 0;
}
}
@Override
public int read() throws IOException {
poll();
if (readableBytes() == 0) {
if (closed.get()) {
return -1;
}
}
if (current != null && current.readableBytes() > 0) {
return current.readByte() & 0xff;
} else {
return read();
}
}
private void poll() {
if (readableBytes() == 0) {
try {
current = queue.poll(50, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}