package org.glassfish.grizzly.http2.utils;
import java.util.logging.Logger;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.WriteResult;
public class ChunkedCompletionHandler implements CompletionHandler<WriteResult> {
private static final Logger LOG = Logger.getLogger(ChunkedCompletionHandler.class.getName());
private final CompletionHandler<WriteResult> parentCompletionHandler;
private boolean isDone;
private int chunksCounter = 1;
private long writtenSize;
public ChunkedCompletionHandler(final CompletionHandler<WriteResult> parentCompletionHandler) {
this.parentCompletionHandler = parentCompletionHandler;
}
public void incChunks() {
chunksCounter++;
}
@Override
public void cancelled() {
LOG.finest("cancelled()");
if (done()) {
if (parentCompletionHandler != null) {
parentCompletionHandler.cancelled();
}
}
}
@Override
public void failed(Throwable throwable) {
LOG.finest(() -> String.format("failed(throwable=%s)", throwable));
if (done()) {
if (parentCompletionHandler != null) {
parentCompletionHandler.failed(throwable);
}
}
}
@Override
public void completed(final WriteResult result) {
LOG.finest(() -> String.format("completed(result=%s)", result));
if (isDone) {
return;
}
if (--chunksCounter == 0) {
done();
final long initialWrittenSize = result.getWrittenSize();
writtenSize += initialWrittenSize;
if (parentCompletionHandler != null) {
try {
result.setWrittenSize(writtenSize);
parentCompletionHandler.completed(result);
} finally {
result.setWrittenSize(initialWrittenSize);
}
}
} else {
updated(result);
writtenSize += result.getWrittenSize();
}
}
@Override
public void updated(final WriteResult result) {
LOG.finest(() -> String.format("updated(result=%s)", result));
if (parentCompletionHandler != null) {
final long initialWrittenSize = result.getWrittenSize();
try {
result.setWrittenSize(writtenSize + initialWrittenSize);
parentCompletionHandler.updated(result);
} finally {
result.setWrittenSize(initialWrittenSize);
}
}
}
private boolean done() {
if (isDone) {
return false;
}
isDone = true;
done0();
return true;
}
protected void done0() {
}
}