home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-05-03 | 6.3 KB | 232 lines |
- /*
- * @(#)PipedInputStream.java 1.12 96/04/02 James Gosling
- *
- * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for NON-COMMERCIAL purposes and without fee is hereby
- * granted provided that this copyright notice appears in all copies. Please
- * refer to the file "copyright.html" for further important copyright and
- * licensing information.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
- * OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
- * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
- * ITS DERIVATIVES.
- */
-
- package java.io;
-
- import java.io.*;
- import java.io.IOException;
-
- /**
- * PipedInputStream must be connected to a PipedOutputStream
- * to be useful. A thread reading from a PipedInputStream recieves data from
- * a thread writing to the PipedOutputStream it is connected to.
- *
- * @see PipedOutputStream
- * @version 96/04/02
- * @author James Gosling
- */
- public
- class PipedInputStream extends InputStream {
- boolean closed = true;
-
- /* REMIND: identification of the read and write sides needs to be
- more sophisticated. Either using thread groups (but what about
- pipes within a thread?) or using finalization (but it may be a
- long time until the next GC). */
- Thread readSide;
- Thread writeSide;
-
- /* The circular buffer into which incoming data is placed */
- private byte buffer[] = new byte[1024];
-
- /*
- * fill and empty pointers. in<0 implies the buffer is empty, in==out
- * implies the buffer is full
- */
- int in = -1;
- int out = 0;
-
- /**
- * Creates an input file from the specified PiledOutputStream.
- * @param src the stream to connect to.
- */
- public PipedInputStream (PipedOutputStream src) throws IOException {
- connect(src);
- }
-
- /**
- * Creates an input file that isn't connected to anything (yet).
- * It must be connected to a PipedOutputStream before being used.
- */
- public PipedInputStream () {
- }
-
- /**
- * Connects this input stream to a sender.
- * @param src The OutputStream to connect to.
- */
- public void connect(PipedOutputStream src) throws IOException {
- src.connect(this);
- }
-
- /**
- * Receives a byte of data. This method will block if no input is
- * available.
- * @param b the byte being received
- * @exception IOException If the pipe is broken.
- */
- synchronized void receive(int b) throws IOException {
- writeSide = Thread.currentThread();
- while (in == out) {
- if ((readSide != null) && !readSide.isAlive()) {
- throw new IOException("Pipe broken");
- }
- /* full: kick any waiting readers */
- notifyAll();
- try {
- wait(1000);
- } catch (InterruptedException ex) {
- throw new java.io.InterruptedIOException();
- }
- }
- if (in < 0) {
- in = 0;
- out = 0;
- }
- buffer[in++] = (byte)(b & 0xFF);
- if (in >= buffer.length) {
- in = 0;
- }
- }
-
- /**
- * Receives data into an array of bytes. This method will
- * block until some input is available.
- * @param b the buffer into which the data is received
- * @param off the start offset of the data
- * @param len the maximum number of bytes received
- * @return the actual number of bytes received, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
- synchronized void receive(byte b[], int off, int len) throws IOException {
- while (--len >= 0) {
- receive(b[off++]);
- }
- }
-
- /**
- * Notifies all waiting threads that the last byte of data has been
- * received.
- */
- synchronized void receivedLast() {
- closed = true;
- notifyAll();
- }
-
- /**
- * Reads a byte of data. This method will block if no input is available.
- * @return the byte read, or -1 if the end of the stream is reached.
- * @exception IOException If the pipe is broken.
- */
- public synchronized int read() throws IOException {
- int trials = 2;
- while (in < 0) {
- readSide = Thread.currentThread();
- if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
- throw new IOException("Pipe broken");
- }
- if (closed) {
- return -1;
- }
-
- /* might be a writer waiting */
- notifyAll();
- try {
- wait(1000);
- } catch (InterruptedException ex) {
- throw new java.io.InterruptedIOException();
- }
- }
- int ret = buffer[out++] & 0xFF;
- if (out >= buffer.length) {
- out = 0;
- }
- if (in == out) {
- /* now empty */
- in = -1;
- }
- return ret;
- }
-
- /**
- * Reads into an array of bytes.
- * Blocks until some input is available.
- * @param b the buffer into which the data is read
- * @param off the start offset of the data
- * @param len the maximum number of bytes read
- * @return the actual number of bytes read, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
- public synchronized int read(byte b[], int off, int len) throws IOException {
- if (len <= 0) {
- return 0;
- }
-
- /* possibly wait on the first character */
- int c = read();
- if (c < 0) {
- return -1;
- }
- b[off] = (byte) c;
- int rlen = 1;
- while ((in >= 0) && (--len > 0)) {
- b[off + rlen] = buffer[out++];
- rlen++;
- if (out >= buffer.length) {
- out = 0;
- }
- if (in == out) {
- /* now empty */
- in = -1;
- }
- }
- return rlen;
- }
-
- /*
- * should be overridden from parentclass (used to always return 0)
- * should this also be synchronized?? -DAB
- */
- public synchronized int available() throws IOException {
- if(in < 0)
- return 0;
- else if(in == out)
- return buffer.length;
- else if (in > out)
- return in - out;
- else
- return in + buffer.length - out;
- }
-
-
- /**
- * Closes the input stream. Must be called
- * to release any resources associated with
- * the stream.
- * @exception IOException If an I/O error has occurred.
- */
- public void close() throws IOException {
- in = -1;
- closed = true;
- }
-
- }
-