/*******************************************************************************
* Copyright (c) 2009, 2011 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.internal.debug.ui.launch.setup;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
class TimeOutInputStream extends FilterInputStream {
private byte buf[];
private int buf_inp = 0;
private int buf_out = 0;
private boolean eof = false;
private IOException err;
private InputStream inp;
private long time = 0;
private Thread thread;
private class Prefetch extends Thread {
public void run() {
try {
for (;;) {
int rd = inp.read();
if (rd < 0) break;
synchronized (TimeOutInputStream.this) {
int new_inp = (buf_inp + 1) % buf.length;
while (new_inp == buf_out) TimeOutInputStream.this.wait();
buf[buf_inp] = (byte)rd;
buf_inp = new_inp;
TimeOutInputStream.this.notify();
}
}
}
catch (InterruptedException x) {
err = new InterruptedIOException();
}
catch (InterruptedIOException x) {
err = x;
}
catch (IOException x) {
err = x;
}
finally {
synchronized (TimeOutInputStream.this) {
eof = true;
TimeOutInputStream.this.notify();
}
}
}
}
TimeOutInputStream(InputStream in, long time) {
this(in, 0x1000, time);
}
TimeOutInputStream(InputStream in, int size, long time) {
super(in);
inp = in;
buf = new byte[size];
this.time = time;
thread = new Prefetch();
thread.start();
}
public void setTimeOut(long time) {
this.time = time;
}
public synchronized int read() throws IOException {
try {
int cnt = 0;
while (buf_inp == buf_out) {
if (err != null) throw new IOException(err.getMessage());
if (eof) return -1;
if (time != 0) {
if (cnt > 0) throw new IOException("Time Out");
wait(time);
cnt++;
}
else {
wait();
}
}
int res = buf[buf_out] & 0xff;
buf_out = (buf_out + 1) % buf.length;
notify();
return res;
}
catch (InterruptedException x) {
throw new InterruptedIOException();
}
}
public synchronized int read(byte b[], int off, int len) throws IOException {
boolean nfy = false;
try {
int res = 0;
while (res < len) {
int cnt = 0;
while (buf_inp == buf_out) {
if (res > 0) return res;
if (err != null) throw new IOException(err.getMessage());
if (eof) return -1;
if (nfy) {
notify();
nfy = false;
}
if (time != 0) {
if (cnt > 0) throw new IOException("Time Out");
wait(time);
cnt++;
}
else {
wait();
}
}
b[off++] = buf[buf_out];
buf_out = (buf_out + 1) % buf.length;
nfy = true;
res++;
}
return res;
}
catch (InterruptedException x) {
throw new InterruptedIOException();
}
finally {
if (nfy) notify();
}
}
public synchronized int available() throws IOException {
return (buf_inp - buf_out + buf.length) % buf.length;
}
public synchronized void close() throws IOException {
super.close();
if (thread != null) {
try {
thread.interrupt();
while (!eof) wait();
thread = null;
}
catch (InterruptedException x) {
throw new InterruptedIOException();
}
}
}
}