home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / sybase / starbuck / java.z / PipedInputStream.java < prev    next >
Text File  |  1996-05-03  |  6KB  |  232 lines

  1. /*
  2.  * @(#)PipedInputStream.java    1.12 96/04/02 James Gosling
  3.  * 
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for NON-COMMERCIAL purposes and without fee is hereby
  8.  * granted provided that this copyright notice appears in all copies. Please
  9.  * refer to the file "copyright.html" for further important copyright and
  10.  * licensing information.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  15.  * OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
  16.  * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  17.  * ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.io;
  21.  
  22. import java.io.*;
  23. import java.io.IOException;
  24.  
  25. /**
  26.  * PipedInputStream must be connected to a PipedOutputStream
  27.  * to be useful.  A thread reading from a PipedInputStream recieves data from
  28.  * a thread writing to the PipedOutputStream it is connected to.
  29.  *
  30.  * @see    PipedOutputStream
  31.  * @version     96/04/02
  32.  * @author    James Gosling
  33.  */
  34. public
  35. class PipedInputStream extends InputStream {
  36.     boolean closed = true;    
  37.  
  38.     /* REMIND: identification of the read and write sides needs to be
  39.        more sophisticated.  Either using thread groups (but what about
  40.        pipes within a thread?) or using finalization (but it may be a
  41.        long time until the next GC). */
  42.     Thread readSide;
  43.     Thread writeSide;
  44.  
  45.     /* The circular buffer into which incoming data is placed */
  46.     private byte buffer[] = new byte[1024];
  47.  
  48.     /*
  49.      * fill and empty pointers.  in<0 implies the buffer is empty, in==out
  50.      * implies the buffer is full
  51.      */
  52.     int in = -1;
  53.     int out = 0;
  54.  
  55.     /**
  56.      * Creates an input file from the specified PiledOutputStream.
  57.      * @param src the stream to connect to.
  58.      */
  59.     public PipedInputStream (PipedOutputStream src) throws IOException {
  60.     connect(src);
  61.     }
  62.  
  63.     /**
  64.      * Creates an input file that isn't connected to anything (yet).
  65.      * It must be connected to a PipedOutputStream before being used.
  66.      */
  67.     public PipedInputStream () {
  68.     }
  69.  
  70.     /**
  71.      * Connects this input stream to a sender.
  72.      * @param src    The OutputStream to connect to.
  73.      */
  74.     public void connect(PipedOutputStream src) throws IOException {
  75.     src.connect(this);
  76.     }
  77.     
  78.     /**
  79.      * Receives a byte of data.  This method will block if no input is
  80.      * available.
  81.      * @param b the byte being received
  82.      * @exception IOException If the pipe is broken.
  83.      */
  84.     synchronized void receive(int b) throws IOException {
  85.     writeSide = Thread.currentThread();
  86.     while (in == out) {
  87.         if ((readSide != null) && !readSide.isAlive()) {
  88.         throw new IOException("Pipe broken");
  89.         }
  90.         /* full: kick any waiting readers */
  91.         notifyAll();    
  92.         try {
  93.             wait(1000);
  94.         } catch (InterruptedException ex) {
  95.         throw new java.io.InterruptedIOException();
  96.         }
  97.     }
  98.     if (in < 0) {
  99.         in = 0;
  100.         out = 0;
  101.     }
  102.     buffer[in++] = (byte)(b & 0xFF);
  103.     if (in >= buffer.length) {
  104.         in = 0;
  105.     }
  106.     }
  107.  
  108.     /**
  109.      * Receives data into an array of bytes.  This method will
  110.      * block until some input is available. 
  111.      * @param b the buffer into which the data is received
  112.      * @param off the start offset of the data
  113.      * @param len the maximum number of bytes received
  114.      * @return the actual number of bytes received, -1 is
  115.      *          returned when the end of the stream is reached. 
  116.      * @exception IOException If an I/O error has occurred. 
  117.      */
  118.     synchronized void receive(byte b[], int off, int len)  throws IOException {
  119.     while (--len >= 0) {
  120.         receive(b[off++]);
  121.     }
  122.     }
  123.  
  124.     /**
  125.      * Notifies all waiting threads that the last byte of data has been
  126.      * received.
  127.      */
  128.     synchronized void receivedLast() {
  129.     closed = true;
  130.     notifyAll();
  131.     }
  132.  
  133.     /**
  134.      * Reads a byte of data. This method will block if no input is available.
  135.      * @return     the byte read, or -1 if the end of the stream is reached.
  136.      * @exception IOException If the pipe is broken.
  137.      */
  138.     public synchronized int read()  throws IOException {
  139.     int trials = 2;
  140.     while (in < 0) {
  141.         readSide = Thread.currentThread();
  142.         if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
  143.         throw new IOException("Pipe broken");
  144.         }
  145.         if (closed) {
  146.         return -1;
  147.         }
  148.  
  149.             /* might be a writer waiting */
  150.         notifyAll();
  151.         try {
  152.             wait(1000);
  153.         } catch (InterruptedException ex) {
  154.         throw new java.io.InterruptedIOException();
  155.         }
  156.      }
  157.     int ret = buffer[out++] & 0xFF;
  158.     if (out >= buffer.length) {
  159.         out = 0;
  160.     }
  161.     if (in == out) {
  162.             /* now empty */
  163.         in = -1;        
  164.     }
  165.     return ret;
  166.     }
  167.  
  168.     /**
  169.      * Reads into an array of bytes.
  170.      * Blocks until some input is available.
  171.      * @param b    the buffer into which the data is read
  172.      * @param off the start offset of the data
  173.      * @param len the maximum number of bytes read
  174.      * @return  the actual number of bytes read, -1 is
  175.      *         returned when the end of the stream is reached.
  176.      * @exception IOException If an I/O error has occurred.
  177.      */
  178.     public synchronized int read(byte b[], int off, int len)  throws IOException {
  179.     if (len <= 0) {
  180.         return 0;
  181.     }
  182.  
  183.         /* possibly wait on the first character */
  184.     int c = read();        
  185.     if (c < 0) {
  186.         return -1;
  187.     }
  188.     b[off] = (byte) c;
  189.     int rlen = 1;
  190.     while ((in >= 0) && (--len > 0)) {
  191.         b[off + rlen] = buffer[out++];
  192.         rlen++;
  193.         if (out >= buffer.length) {
  194.         out = 0;
  195.         }
  196.         if (in == out) {
  197.                 /* now empty */
  198.         in = -1;    
  199.         }
  200.     }
  201.     return rlen;
  202.     }
  203.  
  204.   /*
  205.    * should be overridden from parentclass (used to always return 0)
  206.    * should this also be synchronized?? -DAB
  207.    */
  208.   public synchronized int available() throws IOException {
  209.     if(in < 0)
  210.       return 0;
  211.     else if(in == out)
  212.       return buffer.length;
  213.     else if (in > out)
  214.       return in - out;
  215.     else
  216.       return in + buffer.length - out;
  217.   }
  218.     
  219.  
  220.     /**
  221.      * Closes the input stream. Must be called
  222.      * to release any resources associated with
  223.      * the stream.
  224.      * @exception IOException If an I/O error has occurred.
  225.      */
  226.     public void close()  throws IOException {
  227.     in = -1;
  228.     closed = true;
  229.     }
  230.  
  231. }
  232.