All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aQute.bnd.http.ProgressWrappingStream Maven / Gradle / Ivy

The newest version!
package aQute.bnd.http;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import aQute.bnd.service.progress.ProgressPlugin.Task;

public class ProgressWrappingStream extends InputStream {

	private InputStream			delegate;
	private Task				task;
	private int					size;
	private int					reported;
	private int					read;
	private final long			timeout;
	private final AtomicBoolean	closed	= new AtomicBoolean();
	private long				startNanos;

	public ProgressWrappingStream(InputStream delegate, String name, int size, Task task, long timeout) {
		this.delegate = delegate;
		this.task = task;
		this.size = size;
		this.read = 0;
		this.reported = 0;
		this.timeout = timeout <= 0L ? timeout : TimeUnit.MILLISECONDS.toNanos(timeout);
		this.startNanos = System.nanoTime();
	}

	@Override
	public int read() throws IOException {
		while (!isTimeout()) {
			if (task.isCanceled()) {
				throw new EOFException("Canceled");
			}
			try {
				int data = delegate.read();
				update(data == -1 ? -1 : 1);
				return data;
			} catch (SocketTimeoutException e) {
				if (task.isCanceled())
					throw new EOFException("Canceled");
			}
		}
		throw new EOFException("Timeout");
	}

	private boolean isTimeout() throws IOException {
		if (timeout <= 0)
			return false;

		long elapsed = System.nanoTime() - startNanos;
		if (elapsed >= timeout) {
			close();
			return true;
		}
		return false;
	}

	@Override
	public int read(byte[] buffer) throws IOException {
		while (!isTimeout()) {
			if (task.isCanceled()) {
				throw new EOFException("Canceled");
			}
			try {
				int count = delegate.read(buffer);
				return update(count);
			} catch (SocketTimeoutException e) {
				if (task.isCanceled())
					throw new EOFException("Canceled");
			}
		}
		throw new EOFException("Timeout");
	}

	@Override
	public int read(byte[] buffer, int offset, int length) throws IOException {
		while (!isTimeout()) {
			if (task.isCanceled()) {
				throw new EOFException("Canceled");
			}
			try {
				int count = delegate.read(buffer, offset, length);
				return update(count);
			} catch (SocketTimeoutException e) {
				if (task.isCanceled())
					throw new EOFException("Canceled");
			}
		}
		throw new EOFException("Timeout");
	}

	public int update(int count) throws IOException {

		if (task.isCanceled()) {
			close();
			throw new EOFException("Canceled");
		}

		startNanos = System.nanoTime();

		if (count != -1) {
			read += count;
			int where = (50 + read * 100) / size;
			int delta = where - reported;
			if (delta > 0)
				task.worked(delta);
			this.reported = where;
		} else
			close();
		return count;
	}

	@Override
	public void close() throws IOException {
		if (closed.getAndSet(true)) {
			return;
		}
		try {
			task.done("Finished", null);
		} finally {
			delegate.close();
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy