package org.jabref.logic.net; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import javafx.beans.property.LongProperty; import javafx.beans.property.SimpleLongProperty; /** * An input stream that keeps track of the amount of bytes already read. * Code based on http://stackoverflow.com/a/1339589/873661, but converted to use JavaFX properties instead of listeners */ public class ProgressInputStream extends FilterInputStream { private final long maxNumBytes; private final LongProperty totalNumBytesRead; private final LongProperty progress; public ProgressInputStream(InputStream in, long maxNumBytes) { super(in); this.maxNumBytes = maxNumBytes; this.totalNumBytesRead = new SimpleLongProperty(0); this.progress = new SimpleLongProperty(0); this.progress.bind(totalNumBytesRead.divide(maxNumBytes)); } public long getTotalNumBytesRead() { return totalNumBytesRead.get(); } public LongProperty totalNumBytesReadProperty() { return totalNumBytesRead; } public long getProgress() { return progress.get(); } public LongProperty progressProperty() { return progress; } public long getMaxNumBytes() { return maxNumBytes; } @Override public int read() throws IOException { int b = super.read(); updateProgress(1); return b; } @Override public int read(byte[] b, int off, int len) throws IOException { return (int) updateProgress(super.read(b, off, len)); } @Override public long skip(long n) throws IOException { return updateProgress(super.skip(n)); } @Override public void mark(int readlimit) { throw new UnsupportedOperationException(); } @Override public void reset() throws IOException { throw new UnsupportedOperationException(); } @Override public boolean markSupported() { return false; } private long updateProgress(long numBytesRead) { if (numBytesRead > 0) { totalNumBytesRead.set(totalNumBytesRead.get() + numBytesRead); } return numBytesRead; } }