package net.yacy.data.ymark;
import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* This class monitors the read progress
*
*/
public class MonitoredReader extends FilterReader {
private volatile long mark = 0;
private volatile long location = 0;
private final int threshold;
private final long maxProgress;
private long lastTriggeredLocation = 0;
private ChangeListener listener = null;
public MonitoredReader(Reader in, int threshold, long maxProgress) {
super(in);
this.threshold = threshold;
this.maxProgress = maxProgress;
}
public void addChangeListener(ChangeListener l) {
this.listener = l;
}
protected void triggerChanged(final long location) {
if ( threshold > 0 && Math.abs( location-lastTriggeredLocation ) < threshold )
return;
lastTriggeredLocation = location;
if (listener == null)
return;
listener.stateChanged(new ChangeEvent(this));
}
public long getProgress() {
return this.location;
}
public long maxProgress() {
return this.maxProgress;
}
@Override
public int read() throws IOException {
final int i = super.read();
if ( i != -1 )
triggerChanged(location++);
return i;
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
final int i = super.read(cbuf, off, len);
if ( i != -1 )
triggerChanged(location+=i);
return i;
}
@Override
public int read(char[] cbuf) throws IOException {
final int i = super.read(cbuf);
if ( i != -1 )
triggerChanged(location+=i);
return i;
}
@Override
public int read(CharBuffer target) throws IOException {
final int i = super.read(target);
if ( i != -1 )
triggerChanged(location+=i);
return i;
}
@Override
public long skip(long n) throws IOException {
final long i = super.skip(n);
if ( i != -1 )
triggerChanged(location+=i);
return i;
}
@Override
public synchronized void mark(int readlimit) throws IOException {
super.mark(readlimit);
mark = location;
}
@Override
public synchronized void reset() throws IOException {
super.reset();
if ( location != mark )
triggerChanged(location = mark);
}
}