home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / PushbackInputStream.java < prev    next >
Text File  |  1997-05-21  |  8KB  |  231 lines

  1. /*
  2.  * @(#)PushbackInputStream.java    1.16 97/05/12
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  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
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. package java.io;
  24.  
  25. /**
  26.  * This class is an input stream filter that provides a buffer into which data
  27.  * can be "unread."  An application may unread data at any time by pushing it
  28.  * back into the buffer, as long as the buffer has sufficient room.  Subsequent
  29.  * reads will read all of the pushed-back data in the buffer before reading
  30.  * from the underlying input stream.
  31.  *
  32.  * <p>
  33.  * This functionality is useful when a fragment of code should read 
  34.  * an indefinite number of data bytes that are delimited by 
  35.  * particular byte values. After reading the terminating byte the
  36.  * code fragment can push it back, so that the next read 
  37.  * operation on the input stream will re-read that byte.
  38.  *
  39.  * @author  David Connelly
  40.  * @author  Jonathan Payne
  41.  * @version 1.16, 05/12/97
  42.  * @since   JDK1.0
  43.  */
  44. public
  45. class PushbackInputStream extends FilterInputStream {
  46.     /**
  47.      * The pushback buffer.
  48.      * @since   JDK1.1
  49.      */
  50.     protected byte[] buf;
  51.  
  52.     /**
  53.      * The position within the pushback buffer from which the next byte will
  54.      * be read.  When the buffer is empty, <code>pos</code> is equal to
  55.      * <code>buf.length</code>; when the buffer is full, <code>pos</code> is
  56.      * equal to zero.
  57.      *
  58.      * @since   JDK1.1
  59.      */
  60.     protected int pos;
  61.  
  62.     /**
  63.      * Creates a new pushback input stream with a pushback buffer
  64.      * of the specified size.
  65.      *
  66.      * @param  in    the input stream from which bytes will be read.
  67.      * @param  size  the size of the pushback buffer.
  68.      * @since  JDK1.1
  69.      */
  70.     public PushbackInputStream(InputStream in, int size) {
  71.     super(in);
  72.     this.buf = new byte[size];
  73.     this.pos = size;
  74.     }
  75.  
  76.     /**
  77.      * Creates a new pushback input stream with a one-byte pushback buffer.
  78.      *
  79.      * @param   in   the input stream from which bytes will be read.
  80.      */
  81.     public PushbackInputStream(InputStream in) {
  82.     this(in, 1);
  83.     }
  84.  
  85.     /**
  86.      * Reads the next byte of data from this input stream. The value 
  87.      * byte is returned as an <code>int</code> in the range 
  88.      * <code>0</code> to <code>255</code>. If no byte is available 
  89.      * because the end of the stream has been reached, the value 
  90.      * <code>-1</code> is returned. This method blocks until input data 
  91.      * is available, the end of the stream is detected, or an exception 
  92.      * is thrown. 
  93.      *
  94.      * <p> This method returns the most recently pushed-back byte, if there is
  95.      * one, and otherwise calls the <code>read</code> method of its underlying
  96.      * input stream and returns whatever value that method returns.
  97.      *
  98.      * @return     the next byte of data, or <code>-1</code> if the end of the
  99.      *             stream has been reached.
  100.      * @exception  IOException  if an I/O error occurs.
  101.      * @see        java.io.InputStream#read()
  102.      */
  103.     public int read() throws IOException {
  104.     if (pos < buf.length) {
  105.         return buf[pos++] & 0xff;
  106.     }
  107.     return super.read();
  108.     }
  109.  
  110.     /**
  111.      * Reads up to <code>len</code> bytes of data from this input stream into
  112.      * an array of bytes.  This method first reads any pushed-back bytes; after
  113.      * that, if fewer than than <code>len</code> bytes have been read then it
  114.      * reads from the underlying input stream.  This method blocks until at
  115.      * least 1 byte of input is available.
  116.      *
  117.      * @param      b     the buffer into which the data is read.
  118.      * @param      off   the start offset of the data.
  119.      * @param      len   the maximum number of bytes read.
  120.      * @return     the total number of bytes read into the buffer, or
  121.      *             <code>-1</code> if there is no more data because the end of
  122.      *             the stream has been reached.
  123.      * @exception  IOException  if an I/O error occurs.
  124.      */
  125.     public int read(byte[] b, int off, int len) throws IOException {
  126.     if (len <= 0) {
  127.         return 0;
  128.     }
  129.     int avail = buf.length - pos;
  130.     if (avail > 0) {
  131.         if (len < avail) {
  132.         avail = len;
  133.         }
  134.         System.arraycopy(buf, pos, b, off, avail);
  135.         pos += avail;
  136.         off += avail;
  137.         len -= avail;
  138.     }
  139.     if (len > 0) {
  140.         len = super.read(b, off, len);
  141.         if (len == -1) {
  142.         return avail == 0 ? -1 : avail;
  143.         }
  144.         return avail + len;
  145.     }
  146.     return avail;
  147.     }
  148.  
  149.     /**
  150.      * Pushes back a byte by copying it to the front of the pushback buffer.
  151.      * After this method returns, the next byte to be read will have the value
  152.      * <code>(byte)b</code>.
  153.      *
  154.      * @param      b   the <code>int</code> value whose low-order 
  155.      *             byte is to be pushed back.
  156.      * @exception IOException If there is not enough room in the pushback
  157.      *                  buffer for the byte.
  158.      */
  159.     public void unread(int b) throws IOException {
  160.     if (pos == 0) {
  161.         throw new IOException("Push back buffer is full");
  162.     }
  163.     buf[--pos] = (byte)b;
  164.     }
  165.  
  166.     /**
  167.      * Pushes back a portion of an array of bytes by copying it to the front
  168.      * of the pushback buffer.  After this method returns, the next byte to be
  169.      * read will have the value <code>b[off]</code>, the byte after that will
  170.      * have the value <code>b[off+1]</code>, and so forth.
  171.      *
  172.      * @param b the byte array to push back.
  173.      * @param off the start offset of the data.
  174.      * @param len the number of bytes to push back.
  175.      * @exception IOException If there is not enough room in the pushback
  176.      *                  buffer for the specified number of bytes.
  177.      * @since     JDK1.1
  178.      */
  179.     public void unread(byte[] b, int off, int len) throws IOException {
  180.     if (len > pos) {
  181.         throw new IOException("Push back buffer is full");
  182.     }
  183.     pos -= len;
  184.     System.arraycopy(b, off, buf, pos, len);
  185.     }
  186.  
  187.     /**
  188.      * Pushes back an array of bytes by copying it to the front of the
  189.      * pushback buffer.  After this method returns, the next byte to be read
  190.      * will have the value <code>b[0]</code>, the byte after that will have the
  191.      * value <code>b[1]</code>, and so forth.
  192.      *
  193.      * @param b the byte array to push back
  194.      * @exception IOException If there is not enough room in the pushback
  195.      *                  buffer for the specified number of bytes.
  196.      * @since     JDK1.1
  197.      */
  198.     public void unread(byte[] b) throws IOException {
  199.     unread(b, 0, b.length);
  200.     }
  201.  
  202.     /**
  203.      * Returns the number of bytes that can be read from this input stream
  204.      * without blocking.  This method calls the <code>available</code> method
  205.      * of the underlying input stream; it returns that value plus the number of
  206.      * bytes that have been pushed back.
  207.      *
  208.      * @return     the number of bytes that can be read from the input stream
  209.      *             without blocking.
  210.      * @exception  IOException  if an I/O error occurs.
  211.      * @see        java.io.FilterInputStream#in
  212.      */
  213.     public int available() throws IOException {
  214.     return pos + super.available();
  215.     }
  216.  
  217.     /**
  218.      * Tests if this input stream supports the <code>mark</code> and
  219.      * <code>reset</code> methods, which it does not.
  220.      *
  221.      * @return   <code>false</code>, since this class does not support the
  222.      *           <code>mark</code> and <code>reset</code> methods.
  223.      * @see     java.io.InputStream#mark(int)
  224.      * @see     java.io.InputStream#reset()
  225.      */
  226.     public boolean markSupported() {
  227.     return false;
  228.     }
  229.  
  230. }
  231.