+package org.simantics.scl.rest;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.ext.ReaderInterceptor;
+import javax.ws.rs.ext.ReaderInterceptorContext;
+
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.tuple.Tuple0;
+
+public class ReadProgressInterceptor implements ReaderInterceptor {
+
+ private Function1<Long, Tuple0> callback;
+
+ public ReadProgressInterceptor(Function1<Long, Tuple0> callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
+
+ final InputStream is = context.getInputStream();
+
+ context.setInputStream(new FilterInputStream(is) {
+
+ private long count;
+
+ @Override
+ public int read(byte b[], int off, int len) throws IOException {
+ int read = in.read(b, off, len);
+ if (read > 0) {
+ count += read;
+ callback.apply(count);
+ }
+ return read;
+ }
+
+ @Override
+ public int read() throws IOException {
+ int read = in.read();
+ if (read > 0) {
+ count++;
+ callback.apply(count);
+ }
+ return read;
+ }
+ });
+
+ return context.proceed();
+ }
+
+}