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

  1. /*
  2.  * @(#)PushbackReader.java    1.7 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. /**
  27.  * A character-stream reader that allows characters to be pushed back into the
  28.  * stream.
  29.  *
  30.  * @version     1.7, 97/05/12
  31.  * @author    Mark Reinhold
  32.  * @since    JDK1.1
  33.  */
  34.  
  35. public class PushbackReader extends FilterReader {
  36.  
  37.     /** Pushback buffer */
  38.     private char[] buf;
  39.  
  40.     /** Current position in buffer */
  41.     private int pos;
  42.  
  43.     /**
  44.      * Create a new pushback reader with a pushback buffer of the given size.
  45.      *
  46.      * @param   in   The reader from which characters will be read
  47.      * @param    size The size of the pushback buffer
  48.      */
  49.     public PushbackReader(Reader in, int size) {
  50.     super(in);
  51.     this.buf = new char[size];
  52.     this.pos = size;
  53.     }
  54.  
  55.     /**
  56.      * Create a new pushback reader with a one-character pushback buffer.
  57.      *
  58.      * @param   in  The reader from which characters will be read
  59.      */
  60.     public PushbackReader(Reader in) {
  61.     this(in, 1);
  62.     }
  63.  
  64.     /** Check to make sure that the stream has not been closed. */
  65.     private void ensureOpen() throws IOException {
  66.     if (buf == null)
  67.         throw new IOException("Stream closed");
  68.     }
  69.  
  70.     /**
  71.      * Read a single character.
  72.      *
  73.      * @return     The character read, or -1 if the end of the stream has been
  74.      *             reached
  75.      *
  76.      * @exception  IOException  If an I/O error occurs
  77.      */
  78.     public int read() throws IOException {
  79.     synchronized (lock) {
  80.         ensureOpen();
  81.         if (pos < buf.length)
  82.         return buf[pos++];
  83.         else
  84.         return super.read();
  85.     }
  86.     }
  87.  
  88.     /**
  89.      * Read characters into a portion of an array.
  90.      *
  91.      * @param      cbuf  Destination buffer
  92.      * @param      off   Offset at which to start writing characters
  93.      * @param      len   Maximum number of characters to read
  94.      *
  95.      * @return     The number of characters read, or -1 if the end of the
  96.      *             stream has been reached
  97.      *
  98.      * @exception  IOException  If an I/O error occurs
  99.      */
  100.     public int read(char cbuf[], int off, int len) throws IOException {
  101.     synchronized (lock) {
  102.         ensureOpen();
  103.  
  104.         if (len <= 0)
  105.         return 0;
  106.         int avail = buf.length - pos;
  107.         if (avail > 0) {
  108.         if (len < avail)
  109.             avail = len;
  110.         System.arraycopy(buf, pos, cbuf, off, avail);
  111.         pos += avail;
  112.         off += avail;
  113.         len -= avail;
  114.         }
  115.         if (len > 0) {
  116.         len = super.read(cbuf, off, len);
  117.         if (len == -1) {
  118.             return (avail == 0) ? -1 : avail;
  119.         }
  120.         return avail + len;
  121.         }
  122.         return avail;
  123.     }
  124.     }
  125.  
  126.     /**
  127.      * Push back a single character.
  128.      *
  129.      * @param  c  The character to push back
  130.      *
  131.      * @exception  IOException  If the pushback buffer is full,
  132.      *                          or if some other I/O error occurs
  133.      */
  134.     public void unread(int c) throws IOException {
  135.     synchronized (lock) {
  136.         ensureOpen();
  137.         if (pos == 0)
  138.         throw new IOException("Pushback buffer overflow");
  139.         buf[--pos] = (char) c;
  140.     }
  141.     }
  142.  
  143.     /**
  144.      * Push back a portion of an array of characters by copying it to the
  145.      * front of the pushback buffer.  After this method returns, the next
  146.      * character to be read will have the value <code>cbuf[off]</code>, the
  147.      * character after that will have the value <code>cbuf[off+1]</code>, and
  148.      * so forth.
  149.      *
  150.      * @param  cbuf  Character array
  151.      * @param  off   Offset of first character to push back
  152.      * @param  len   Number of characters to push back
  153.      *
  154.      * @exception  IOException  If there is insufficient room in the pushback
  155.      *                          buffer, or if some other I/O error occurs
  156.      */
  157.     public void unread(char cbuf[], int off, int len) throws IOException {
  158.     synchronized (lock) {
  159.         ensureOpen();
  160.         if (len > pos)
  161.         throw new IOException("Pushback buffer overflow");
  162.         pos -= len;
  163.         System.arraycopy(cbuf, off, buf, pos, len);
  164.     }
  165.     }
  166.  
  167.     /**
  168.      * Push back an array of characters by copying it to the front of the
  169.      * pushback buffer.  After this method returns, the next character to be
  170.      * read will have the value <code>cbuf[0]</code>, the character after that
  171.      * will have the value <code>cbuf[1]</code>, and so forth.
  172.      *
  173.      * @param  cbuf  Character array to push back
  174.      *
  175.      * @exception  IOException  If there is insufficient room in the pushback
  176.      *                          buffer, or if some other I/O error occurs
  177.      */
  178.     public void unread(char cbuf[]) throws IOException {
  179.     unread(cbuf, 0, cbuf.length);
  180.     }
  181.  
  182.     /**
  183.      * Tell whether this stream is ready to be read.
  184.      *
  185.      * @exception  IOException  If an I/O error occurs
  186.      */
  187.     public boolean ready() throws IOException {
  188.     synchronized (lock) {
  189.         ensureOpen();
  190.         return (pos < buf.length) || super.ready();
  191.     }
  192.     }
  193.  
  194.     /**
  195.      * Tell whether this stream supports the mark() operation, which it does
  196.      * not.
  197.      */
  198.     public boolean markSupported() {
  199.     return false;
  200.     }
  201.  
  202.     /**
  203.      * Close the stream.
  204.      *
  205.      * @exception  IOException  If an I/O error occurs
  206.      */
  207.     public void close() throws IOException {
  208.     super.close();
  209.     buf = null;
  210.     }
  211.  
  212. }
  213.