/* Copyright (C) 1998, 1999  Cygnus Solutions

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */
 
package java.io;

/**
 * @author Warren Levy <warrenl@cygnus.com>
 * @date October 29, 1998.  
 */
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
 * Status:  Believed complete and correct.
 */
 
public class PipedInputStream extends InputStream
{
  /* The size of the pipe's circular input buffer. */
  protected static final int PIPE_SIZE = 1024;

  /* The circular buffer into which incoming data is placed. */
  protected byte[] buffer;

  /* The index in the buffer at which the next byte of data will be stored. */
  protected int in = -1;

  /* The index in the buffer at which the next byte of data will be read. */
  protected int out = 0;

  /* The output stream this is connected to; used to check for errors. */
  private PipedOutputStream po = null;

  /* Flag to indicate that the output stream was closed. */
  private boolean outClosed = false;

  public PipedInputStream(PipedOutputStream src) throws IOException
  {
    buffer = new byte[PIPE_SIZE];
    connect(src);
  }

  public PipedInputStream()
  {
    buffer = new byte[PIPE_SIZE];
  }

  public synchronized int available() throws IOException
  {
    if (in < 0)
      return 0;

    if (in > out)
      return in - out;

    // Buffer has wrapped around.
    return buffer.length - out + in;
  }

  public void close() throws IOException
  {
    buffer = null;
    po = null;

    // Mark as empty for available method.
    in = -1;
  }

  public void connect(PipedOutputStream src) throws IOException
  {
    if (buffer == null)
      throw new IOException("pipe closed");

    if (po != null)
      if (po == src)
	return;
      else
        throw new IOException("pipe already connected");

    po = src;
    try
    {
      src.connect(this);
    }
    catch (IOException ex)
    {
      po = null;
      throw ex;
    }
  }

  public synchronized int read() throws IOException
  {
    // TBD: Spec says to throw IOException if thread writing to output stream
    // died.  What does this really mean?  Theoretically, multiple threads
    // could be writing to this object.  Do you track the first, last, or
    // all of them?
    if (po == null)
      if (buffer == null)
        throw new IOException("pipe closed");
      else
        throw new IOException("pipe unconnected");

    // Block until there's something to read or output stream was closed.
    while (in < 0)
      try
	{
	  if (outClosed)
	    return -1;
	  wait();
	}
      catch (InterruptedException ex)
       {
	 throw new InterruptedIOException();
       }

    // Let other threads know there's room to write now.
    notifyAll();

    int retval = buffer[out++] & 0xFF;

    // Wrap back around if at end of the array.
    if (out >= buffer.length)
      out = 0;

    // When the last byte available is read, mark the buffer as empty.
    if (out == in)
      {
        in = -1;
	out = 0;
      }
      
    return retval;
  }

  public synchronized int read(byte[] b, int off, int len) throws IOException
  {
    if (off < 0 || len < 0 || off + len > b.length)
      throw new ArrayIndexOutOfBoundsException();

    // TBD: Spec says to throw IOException if thread writing to output stream
    // died.  What does this really mean?  Theoretically, multiple threads
    // could be writing to this object.  Do you track the first, last, or
    // all of them?
    if (po == null)
      if (buffer == null)
        throw new IOException("pipe closed");
      else
        throw new IOException("pipe unconnected");

    // Block until there's something to read or output stream was closed.
    while (in < 0)
      try
	{
	  if (outClosed)
	    return -1;
	  wait();
	}
      catch (InterruptedException ex)
       {
	 throw new InterruptedIOException();
       }

    // Let other threads know there's room to write now.
    notifyAll();

    int numRead;
    len = Math.min(len, available());
    if (in <= out && len >= (numRead = buffer.length - out))
      {
	// Buffer has wrapped around; need to copy in 2 steps.
	// Copy to the end of the buffer first; second copy may be of zero
	// bytes but that is ok.  Doing it that way saves having to check
	// later if 'out' has grown to buffer.length.
        System.arraycopy(buffer, out, b, off, numRead);
	len -= numRead;
	off += numRead;
	out = 0;
      }
    else
      numRead = 0;

    System.arraycopy(buffer, out, b, off, len);
    numRead += len;
    out += len;

    // When the last byte available is read, mark the buffer as empty.
    if (out == in)
      {
        in = -1;
	out = 0;
      }

    return numRead;
  }

  protected synchronized void receive(int b) throws IOException
  {
    if (buffer == null)
      throw new IOException("pipe closed");

    // TBD: Spec says to throw IOException if thread reading from input stream
    // died.  What does this really mean?  Theoretically, multiple threads
    // could be reading to this object (why else would 'read' be synchronized?).
    // Do you track the first, last, or all of them?

    if (b < 0)
      {
        outClosed = true;
	notifyAll();	// In case someone was blocked in a read.
	return;
      }

    // Block until there's room in the pipe.
    while (in == out)
      try
	{
	  wait();
	}
      catch (InterruptedException ex)
       {
	 throw new InterruptedIOException();
       }

    // Check if buffer is empty.
    if (in < 0)
      in = 0;

    buffer[in++] = (byte) b;

    // Wrap back around if at end of the array.
    if (in >= buffer.length)
      in = 0;

    // Let other threads know there's something to read when this returns.
    notifyAll();
  }
}
