package com.qiniu.android.http;
import com.qiniu.android.utils.AsyncRun;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;
/**
* Created by bailong on 16/1/8.
*/
public final class CountingRequestBody extends RequestBody {
private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE
private final RequestBody body;
private final ProgressHandler progress;
private final CancellationHandler cancellationHandler;
public CountingRequestBody(RequestBody body, ProgressHandler progress,
CancellationHandler cancellationHandler) {
this.body = body;
this.progress = progress;
this.cancellationHandler = cancellationHandler;
}
@Override
public long contentLength() throws IOException {
return body.contentLength();
}
@Override
public MediaType contentType() {
return body.contentType();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
BufferedSink bufferedSink;
CountingSink countingSink = new CountingSink(sink);
bufferedSink = Okio.buffer(countingSink);
body.writeTo(bufferedSink);
bufferedSink.flush();
}
protected final class CountingSink extends ForwardingSink {
private int bytesWritten = 0;
public CountingSink(Sink delegate) {
super(delegate);
}
@Override
public void write(Buffer source, long byteCount) throws IOException {
if (cancellationHandler == null && progress == null) {
super.write(source, byteCount);
return;
}
if (cancellationHandler != null && cancellationHandler.isCancelled()) {
throw new CancellationHandler.CancellationException();
}
super.write(source, byteCount);
bytesWritten += byteCount;
if (progress != null) {
AsyncRun.runInMain(new Runnable() {
@Override
public void run() {
try {
progress.onProgress(bytesWritten, (int) contentLength());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
}
}