/* PipedReader.java -- Read portion of piped character streams.
   Copyright (C) 1998, 1999, 2000, 2001 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */

package java.io;

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

/**
  * An input stream that reads characters from a piped writer to which it is 
  * connected. 
  * <p>
  * Data is read and written to an internal buffer.  It is highly recommended
  * that the <code>PipedReader</code> and connected <code>PipedWriter</code>
  * be part of different threads.  If they are not, there is a possibility
  * that 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 PipedReader extends Reader
{
  /** PipedWriter to which this is connected. Null only if this 
    * Reader hasn't been connected yet. */
  PipedWriter source;

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

  /**
    * The size of the internal buffer used for input/output.
    */
  static final int PIPE_SIZE = 2048;

  /**
    * This is the internal circular buffer used for storing chars written
    * to the pipe and from which chars are read by this stream
    */
  char[] buffer = new char[PIPE_SIZE];

  /**
    * The index into buffer where the next char from the connected
    * <code>PipedWriter</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.
    */
  int in = -1;

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

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

  /**
    * Creates a new <code>PipedReader</code> that is not connected to a 
    * <code>PipedWriter</code>.  It must be connected before chars can 
    * be read from this stream.
    */
  public PipedReader()
  {
  }

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

  /**
    * This method connects this stream to the passed in <code>PipedWriter</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 src The <code>PipedWriter</code> to connect this stream to
    *
    * @exception IOException If this PipedReader or <code>source</code> 
    *                        has been connected already.
    */
  public void connect(PipedWriter 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 is used by the connected <code>PipedWriter</code> to
    * write chars into the buffer.
    *
    * @param buf The array containing chars to write to this stream
    * @param offset The offset into the array to start writing from
    * @param len The number of chars to write.
    *
    * @exception IOException If an error occurs
    * @specnote This code should be in PipedWriter.write, but we
    *           put it here in order to support that bizarre recieve(int)
    *           method.
    */  
  void receive(char[] buf, int offset, int len)
    throws IOException
  {
    synchronized (lock)
    {
      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.
		  lock.notifyAll();
		  lock.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 chars 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 chars until the pipe is filled, wrapping if neccessary.
	  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.
      lock.notifyAll();
    }
  }
  
  /**
    * This method reads chars from the stream into a caller supplied buffer.
    * It starts storing chars at position <code>offset</code> into the buffer and
    * reads a maximum of <code>len</code> chars.  Note that this method can actually
    * read fewer than <code>len</code> chars.  The actual number of chars read is
    * returned.  A -1 is returned to indicated that no chars 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 chars are available to be read.
    *
    * @param buf The buffer into which chars will be stored
    * @param offset The index into the buffer at which to start writing.
    * @param len The maximum number of chars to read.
    */
  public int read() throws IOException
  {
    // Method operates by calling the multichar 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);

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

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

      int total = 0;
      int copylen;

      while (true)
	{
	  // Figure out how many chars 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 Writer that there is now space
	      // to write.
	      lock.notifyAll();
	      return total;
	    }
	}
    }
  }
  
  public boolean ready() throws IOException
  {
    // The JDK 1.3 implementation does not appear to check for the closed or 
    // unconnected stream conditions here.  However, checking for a
    // closed stream is explicitly required by the JDK 1.2 and 1.3
    // documentation (for Reader.close()), so we do it.
    
    synchronized (lock)
    {
      if (closed)
	throw new IOException("Pipe closed");

      if (in < 0)
	return false;

      int count;
      if (out < in)
	count = in - out;
      else
	count = (buffer.length - out) - in;

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