public int read (char buf[], int offset, int count) throws IOException { if (closed) throw new IOException ("closed"); if (count < 0) throw new ArrayIndexOutOfBoundsException (); int toCopy = count; synchronized (lock) { while (toCopy > 0) {    while (in == -1) { if (writer.isClosed()) { if (toCopy < count) return count - toCopy; return -1; }
read() throws IOException { char[] buf = new char[1];
  public int read (char buf[], int offset, int count) throws IOException  {    if (closed)      throw new IOException ("closed");    if (count < 0)      throw new ArrayIndexOutOfBoundsException ();    int toCopy = count;    synchronized (lock)      {	while (toCopy > 0)	  {	    // Wait for data in the pipe.  If the writer is closed and	    // no data has been copied into the output buffer, return	    // the magic EOF number.	    while (in == -1)	      {		if (writer.isClosed())		  {		    if (toCopy < count)		      return count - toCopy;		    return -1;		  }		// Note that JCL doesn't say this is the right thing		// to do.  Still, it feels right, and we must deal		// with an interrupt somehow.		try		  {		    lock.wait();		  }		catch (InterruptedException e)		  {		    InterruptedIOException io		      = new InterruptedIOException (e.getMessage());		    io.bytesTransferred = count - toCopy;		    throw io;		  }	      }	    // Now copy some data from pipe into user buffer.	    int len;	    if (in < out)	      len = pipeBuffer.length - out;	    else	      len = in - out;	    len = len > toCopy ? toCopy : len;	    System.arraycopy(pipeBuffer, out, buf, offset, len);	    out += len;	    if (out == pipeBuffer.length)	      out = 0;	    toCopy -= len;	    offset += len;	    // If we've read all the data, then reset so that we know	    // there is nothing left to be read.	    if (in == out)	      in = -1;	    // Tell anybody waiting for space in the buffer.	    lock.notifyAll();	  }      }    return count;  }