Merge branch 'upstream-sep2019-sfix' into subtree
[nikiroo-utils.git] / src / jexer / io / TimeoutInputStream.java
diff --git a/src/jexer/io/TimeoutInputStream.java b/src/jexer/io/TimeoutInputStream.java
deleted file mode 100644 (file)
index db9eb4a..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Jexer - Java Text User Interface
- *
- * The MIT License (MIT)
- *
- * Copyright (C) 2017 Kevin Lamonte
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * @author Kevin Lamonte [kevin.lamonte@gmail.com]
- * @version 1
- */
-package jexer.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class provides an optional millisecond timeout on its read()
- * operations.  This permits callers to bail out rather than block.
- */
-public class TimeoutInputStream extends InputStream {
-
-    /**
-     * The wrapped stream.
-     */
-    private InputStream stream;
-
-    /**
-     * The timeout value in millis.  If it takes longer than this for bytes
-     * to be available for read then a ReadTimeoutException is thrown.  A
-     * value of 0 means to block as a normal InputStream would.
-     */
-    private int timeoutMillis;
-
-    /**
-     * If true, the current read() will timeout soon.
-     */
-    private volatile boolean cancel = false;
-
-    /**
-     * Request that the current read() operation timeout immediately.
-     */
-    public synchronized void cancelRead() {
-        cancel = true;
-    }
-
-    /**
-     * Public constructor, at the default timeout of 10000 millis (10
-     * seconds).
-     *
-     * @param stream the wrapped InputStream
-     */
-    public TimeoutInputStream(final InputStream stream) {
-        this.stream             = stream;
-        this.timeoutMillis      = 10000;
-    }
-
-    /**
-     * Public constructor.
-     *
-     * @param stream the wrapped InputStream
-     * @param timeoutMillis the timeout value in millis.  If it takes longer
-     * than this for bytes to be available for read then a
-     * ReadTimeoutException is thrown.  A value of 0 means to block as a
-     * normal InputStream would.
-     */
-    public TimeoutInputStream(final InputStream stream,
-        final int timeoutMillis) {
-
-        if (timeoutMillis < 0) {
-            throw new IllegalArgumentException("Invalid timeoutMillis value, " +
-                "must be >= 0");
-        }
-
-        this.stream             = stream;
-        this.timeoutMillis      = timeoutMillis;
-    }
-
-    /**
-     * Reads the next byte of data from the input stream.
-     *
-     * @return the next byte of data, or -1 if there is no more data because
-     * the end of the stream has been reached.
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public int read() throws IOException {
-
-        if (timeoutMillis == 0) {
-            // Block on the read().
-            return stream.read();
-        }
-
-        if (stream.available() > 0) {
-            // A byte is available now, return it.
-            return stream.read();
-        }
-
-        // We will wait up to timeoutMillis to see if a byte is available.
-        // If not, we throw ReadTimeoutException.
-        long checkTime = System.currentTimeMillis();
-        while (stream.available() == 0) {
-            long now = System.currentTimeMillis();
-            synchronized (this) {
-                if ((now - checkTime > timeoutMillis) || (cancel == true)) {
-                    if (cancel == true) {
-                        cancel = false;
-                    }
-                    throw new ReadTimeoutException("Timeout on read(): " +
-                        (int) (now - checkTime) + " millis and still no data");
-                }
-            }
-            try {
-                // How long do we sleep for, eh?  For now we will go with 2
-                // millis.
-                Thread.sleep(2);
-            } catch (InterruptedException e) {
-                // SQUASH
-            }
-        }
-
-        if (stream.available() > 0) {
-            // A byte is available now, return it.
-            return stream.read();
-        }
-
-        throw new IOException("InputStream claimed a byte was available, but " +
-            "now it is not.  What is going on?");
-    }
-
-    /**
-     * Reads some number of bytes from the input stream and stores them into
-     * the buffer array b.
-     *
-     * @param b the buffer into which the data is read.
-     * @return the total number of bytes read into the buffer, or -1 if there
-     * is no more data because the end of the stream has been reached.
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public int read(final byte[] b) throws IOException {
-        if (timeoutMillis == 0) {
-            // Block on the read().
-            return stream.read(b);
-        }
-
-        int remaining = b.length;
-
-        if (stream.available() >= remaining) {
-            // Enough bytes are available now, return them.
-            return stream.read(b);
-        }
-
-        while (remaining > 0) {
-
-            // We will wait up to timeoutMillis to see if a byte is
-            // available.  If not, we throw ReadTimeoutException.
-            long checkTime = System.currentTimeMillis();
-            while (stream.available() == 0) {
-                long now = System.currentTimeMillis();
-
-                synchronized (this) {
-                    if ((now - checkTime > timeoutMillis) || (cancel == true)) {
-                        if (cancel == true) {
-                            cancel = false;
-                        }
-                        throw new ReadTimeoutException("Timeout on read(): " +
-                            (int) (now - checkTime) + " millis and still no " +
-                            "data");
-                    }
-                }
-                try {
-                    // How long do we sleep for, eh?  For now we will go with
-                    // 2 millis.
-                    Thread.sleep(2);
-                } catch (InterruptedException e) {
-                    // SQUASH
-                }
-            }
-
-            if (stream.available() > 0) {
-                // At least one byte is available now, read it.
-                int n = stream.available();
-                if (remaining < n) {
-                    n = remaining;
-                }
-                int rc = stream.read(b, b.length - remaining, n);
-                if (rc == -1) {
-                    // This shouldn't happen.
-                    throw new IOException("InputStream claimed bytes were " +
-                        "available, but read() returned -1.  What is going " +
-                        "on?");
-                }
-                remaining -= rc;
-                return rc;
-            }
-        }
-
-        throw new IOException("InputStream claimed all bytes were available, " +
-            "but now it is not.  What is going on?");
-    }
-
-    /**
-     * Reads up to len bytes of data from the input stream into an array of
-     * bytes.
-     *
-     * @param b the buffer into which the data is read.
-     * @param off the start offset in array b at which the data is written.
-     * @param len the maximum number of bytes to read.
-     * @return the total number of bytes read into the buffer, or -1 if there
-     * is no more data because the end of the stream has been reached.
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public int read(final byte[] b, final int off,
-        final int len) throws IOException {
-
-        if (timeoutMillis == 0) {
-            // Block on the read().
-            return stream.read(b);
-        }
-
-        int remaining = len;
-
-        if (stream.available() >= remaining) {
-            // Enough bytes are available now, return them.
-            return stream.read(b, off, remaining);
-        }
-
-        while (remaining > 0) {
-
-            // We will wait up to timeoutMillis to see if a byte is
-            // available.  If not, we throw ReadTimeoutException.
-            long checkTime = System.currentTimeMillis();
-            while (stream.available() == 0) {
-                long now = System.currentTimeMillis();
-                synchronized (this) {
-                    if ((now - checkTime > timeoutMillis) || (cancel == true)) {
-                        if (cancel == true) {
-                            cancel = false;
-                        }
-                        throw new ReadTimeoutException("Timeout on read(): " +
-                            (int) (now - checkTime) + " millis and still no " +
-                            "data");
-                    }
-                }
-                try {
-                    // How long do we sleep for, eh?  For now we will go with
-                    // 2 millis.
-                    Thread.sleep(2);
-                } catch (InterruptedException e) {
-                    // SQUASH
-                }
-            }
-
-            if (stream.available() > 0) {
-                // At least one byte is available now, read it.
-                int n = stream.available();
-                if (remaining < n) {
-                    n = remaining;
-                }
-                int rc = stream.read(b, off + len - remaining, n);
-                if (rc == -1) {
-                    // This shouldn't happen.
-                    throw new IOException("InputStream claimed bytes were " +
-                        "available, but read() returned -1.  What is going " +
-                        "on?");
-                }
-                return rc;
-            }
-        }
-
-        throw new IOException("InputStream claimed all bytes were available, " +
-            "but now it is not.  What is going on?");
-    }
-
-    /**
-     * Returns an estimate of the number of bytes that can be read (or
-     * skipped over) from this input stream without blocking by the next
-     * invocation of a method for this input stream.
-     *
-     * @return an estimate of the number of bytes that can be read (or
-     * skipped over) from this input stream without blocking or 0 when it
-     * reaches the end of the input stream.
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public int available() throws IOException {
-        return stream.available();
-    }
-
-    /**
-     * Closes this input stream and releases any system resources associated
-     * with the stream.
-     *
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public void close() throws IOException {
-        stream.close();
-    }
-
-    /**
-     * Marks the current position in this input stream.
-     *
-     * @param readLimit the maximum limit of bytes that can be read before
-     * the mark position becomes invalid
-     */
-    @Override
-    public void mark(final int readLimit) {
-        stream.mark(readLimit);
-    }
-
-    /**
-     * Tests if this input stream supports the mark and reset methods.
-     *
-     * @return true if this stream instance supports the mark and reset
-     * methods; false otherwise
-     */
-    @Override
-    public boolean markSupported() {
-        return stream.markSupported();
-    }
-
-    /**
-     * Repositions this stream to the position at the time the mark method
-     * was last called on this input stream.
-     *
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public void reset() throws IOException {
-        stream.reset();
-    }
-
-    /**
-     * Skips over and discards n bytes of data from this input stream.
-     *
-     * @param n the number of bytes to be skipped
-     * @return the actual number of bytes skipped
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public long skip(final long n) throws IOException {
-        return stream.skip(n);
-    }
-
-}