home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / VCAFE.3.0A / Main.bin / PushbackReader.java < prev    next >
Text File  |  1998-09-22  |  6KB  |  205 lines

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