/* PipedInputStream.java -- Read portion of piped streams.
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.io;

// NOTE: This implementation is very similar to that of PipedReader.  If you
// fix a bug in here, chances are you should make a similar change to the
// PipedReader code.

/**
  * An input stream that reads its bytes from an output stream
  * to which it is connected.
  * <p>
  * Data is read and written to an internal buffer.  It is highly recommended
  * that the <code>PipedInputStream</code> and connected
  * <code>PipedOutputStream</code>
  * be part of different threads.  If they are not, the read and write
  * operations could deadlock their thread.
  *
  * @specnote The JDK implementation appears to have some undocumented
  *           functionality where it keeps track of what thread is writing
  *           to pipe and throws an IOException if that thread susequently
  *           dies. This behaviour seems dubious and unreliable - we don't
  *           implement it.
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  */
public class PipedInputStream extends InputStream
{
  /** PipedOutputStream to which this is connected. Null only if this
    * InputStream hasn't been connected yet. */
  PipedOutputStream source;

  /** Set to true if close() has been called on this InputStream. */
  boolean closed;


  /**
   * The size of the internal buffer used for input/output.
   */
  /* The "Constant Field Values" Javadoc of the Sun J2SE 1.4
   * specifies 1024.
   */
  protected static final int PIPE_SIZE = 1024;


  /**
    * This is the internal circular buffer used for storing bytes written
    * to the pipe and from which bytes are read by this stream
    */
  protected byte[] buffer = null;

  /**
    * The index into buffer where the next byte from the connected
    * <code>PipedOutputStream</code> will be written. If this variable is
    * equal to <code>out</code>, then the buffer is full. If set to < 0,
    * the buffer is empty.
    */
  protected int in = -1;

  /**
    * This index into the buffer where bytes will be read from.
    */
  protected int out = 0;

  /** Buffer used to implement single-argument read/receive */
  private byte[] read_buf = new byte[1];

  /**
    * Creates a new <code>PipedInputStream</code> that is not connected to a
    * <code>PipedOutputStream</code>.  It must be connected before bytes can
    * be read from this stream.
    */
  public PipedInputStream()
  {
    this(PIPE_SIZE);
  }

  /**
   * Creates a new <code>PipedInputStream</code> of the given size that is not
   * connected to a <code>PipedOutputStream</code>.
   * It must be connected before bytes can be read from this stream.
   *
   * @since 1.6
   * @since IllegalArgumentException If pipeSize <= 0.
   */
  public PipedInputStream(int pipeSize) throws IllegalArgumentException
  {
    if (pipeSize <= 0)
      throw new IllegalArgumentException("pipeSize must be > 0");

    this.buffer = new byte[pipeSize];
  }

  /**
    * This constructor creates a new <code>PipedInputStream</code> and connects
    * it to the passed in <code>PipedOutputStream</code>. The stream is then
    * ready for reading.
    *
    * @param source The <code>PipedOutputStream</code> to connect this
    * stream to
    *
    * @exception IOException If <code>source</code> is already connected.
    */
  public PipedInputStream(PipedOutputStream source) throws IOException
  {
    this();
    connect(source);
  }

  /**
   * This constructor creates a new <code>PipedInputStream</code> of the given
   * size and connects it to the passed in <code>PipedOutputStream</code>.
   * The stream is then ready for reading.
   *
   * @param source The <code>PipedOutputStream</code> to connect this
   * stream to
   *
   * @since 1.6
   * @exception IOException If <code>source</code> is already connected.
   */
 public PipedInputStream(PipedOutputStream source, int pipeSize)
   throws IOException
 {
   this(pipeSize);
   connect(source);
 }

  /**
    * This method connects this stream to the passed in
    * <code>PipedOutputStream</code>.
    * This stream is then ready for reading.  If this stream is already
    * connected or has been previously closed, then an exception is thrown
    *
    * @param source The <code>PipedOutputStream</code> to connect this stream to
    *
    * @exception IOException If this PipedInputStream or <code>source</code>
    *                        has been connected already.
    */
  public void connect(PipedOutputStream source) throws IOException
  {
    // The JDK (1.3) does not appear to check for a previously closed
    // connection here.

    if (this.source != null || source.sink != null)
      throw new IOException ("Already connected");

    source.sink = this;
    this.source = source;
  }

  /**
  * This method receives a byte of input from the source PipedOutputStream.
  * If the internal circular buffer is full, this method blocks.
  *
  * @param val The byte to write to this stream
  *
  * @exception IOException if error occurs
  * @specnote Weird. This method must be some sort of accident.
  */
  protected synchronized void receive(int val) throws IOException
  {
    read_buf[0] = (byte) (val & 0xff);
    receive (read_buf, 0, 1);
  }

  /**
    * This method is used by the connected <code>PipedOutputStream</code> to
    * write bytes into the buffer.
    *
    * @param buf The array containing bytes to write to this stream
    * @param offset The offset into the array to start writing from
    * @param len The number of bytes to write.
    *
    * @exception IOException If an error occurs
    * @specnote This code should be in PipedOutputStream.write, but we
    *           put it here in order to support that bizarre recieve(int)
    *           method.
    */
  synchronized void receive(byte[] buf, int offset, int len)
    throws IOException
  {
    if (closed)
      throw new IOException ("Pipe closed");

    int bufpos = offset;
    int copylen;

    while (len > 0)
      {
        try
          {
            while (in == out)
              {
                // The pipe is full. Wake up any readers and wait for them.
                notifyAll();
                wait();
                // The pipe could have been closed while we were waiting.
                if (closed)
                  throw new IOException ("Pipe closed");
              }
          }
        catch (InterruptedException ix)
          {
            throw new InterruptedIOException ();
          }

        if (in < 0) // The pipe is empty.
          in = 0;

        // Figure out how many bytes from buf can be copied without
        // overrunning out or going past the length of the buffer.
        if (in < out)
          copylen = Math.min (len, out - in);
        else
          copylen = Math.min (len, buffer.length - in);

        // Copy bytes until the pipe is filled, wrapping if necessary.
        System.arraycopy(buf, bufpos, buffer, in, copylen);
        len -= copylen;
        bufpos += copylen;
        in += copylen;
        if (in == buffer.length)
          in = 0;
      }
    // Notify readers that new data is in the pipe.
    notifyAll();
  }

  /**
    * This method reads one byte from the stream.
    * -1 is returned to indicated that no bytes can be read
    * because the end of the stream was reached.  If the stream is already
    * closed, a -1 will again be returned to indicate the end of the stream.
    *
    * <p>This method will block if no byte is available to be read.</p>
    *
    * @return the value of the read byte value, or -1 of the end of the stream
    * was reached
    *
    * @throws IOException if an error occured
    */
  public int read() throws IOException
  {
    // Method operates by calling the multibyte overloaded read method
    // Note that read_buf is an internal instance variable.  I allocate it
    // there to avoid constant reallocation overhead for applications that
    // call this method in a loop at the cost of some unneeded overhead
    // if this method is never called.

    int r = read(read_buf, 0, 1);
    return r != -1 ? (read_buf[0] & 0xff) : -1;
  }

  /**
    * This method reads bytes from the stream into a caller supplied buffer.
    * It starts storing bytes at position <code>offset</code> into the
    * buffer and
    * reads a maximum of <code>len</code> bytes.  Note that this method
    * can actually
    * read fewer than <code>len</code> bytes.  The actual number of bytes
    * read is
    * returned.  A -1 is returned to indicated that no bytes can be read
    * because the end of the stream was reached - ie close() was called on the
    * connected PipedOutputStream.
    * <p>
    * This method will block if no bytes are available to be read.
    *
    * @param buf The buffer into which bytes will be stored
    * @param offset The index into the buffer at which to start writing.
    * @param len The maximum number of bytes to read.
    *
    * @exception IOException If <code>close()</code> was called on this Piped
    *                        InputStream.
    */
  public synchronized int read(byte[] buf, int offset, int len)
    throws IOException
  {
    if (source == null)
      throw new IOException ("Not connected");
    if (closed)
      throw new IOException ("Pipe closed");

    // Don't block if nothing was requested.
    if (len == 0)
      return 0;

    // If the buffer is empty, wait until there is something in the pipe
    // to read.
    try
      {
        while (in < 0)
          {
            if (source.closed)
              return -1;
            wait();
          }
      }
    catch (InterruptedException ix)
      {
        throw new InterruptedIOException();
      }

    int total = 0;
    int copylen;

    while (true)
      {
        // Figure out how many bytes from the pipe can be copied without
        // overrunning in or going past the length of buf.
        if (out < in)
          copylen = Math.min (len, in - out);
        else
          copylen = Math.min (len, buffer.length - out);

        System.arraycopy (buffer, out, buf, offset, copylen);
        offset += copylen;
        len -= copylen;
        out += copylen;
        total += copylen;

        if (out == buffer.length)
          out = 0;

        if (out == in)
          {
            // Pipe is now empty.
            in = -1;
            out = 0;
          }

        // If output buffer is filled or the pipe is empty, we're done.
        if (len == 0 || in == -1)
          {
            // Notify any waiting outputstream that there is now space
            // to write.
            notifyAll();
            return total;
          }
      }
  }

  /**
    * This method returns the number of bytes that can be read from this stream
    * before blocking could occur.  This is the number of bytes that are
    * currently unread in the internal circular buffer.  Note that once this
    * many additional bytes are read, the stream may block on a subsequent
    * read, but it not guaranteed to block.
    *
    * @return The number of bytes that can be read before blocking might occur
    *
    * @exception IOException If an error occurs
    */
  public synchronized int available() throws IOException
  {
    // The JDK 1.3 implementation does not appear to check for the closed or
    // unconnected stream conditions here.

    if (in < 0)
      return 0;
    else if (out < in)
      return in - out;
    else
      return (buffer.length - out) + in;
  }

  /**
  * This methods closes the stream so that no more data can be read
  * from it.
  *
  * @exception IOException If an error occurs
  */
  public synchronized void close() throws IOException
  {
    closed = true;
    // Wake any thread which may be in receive() waiting to write data.
    notifyAll();
  }
}
