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

  1. /*
  2.  * @(#)InputStreamReader.java    1.13 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. import sun.io.ByteToCharConverter;
  18. import sun.io.ConversionBufferFullException;
  19.  
  20.  
  21. /**
  22.  * An InputStreamReader is a bridge from byte streams to character streams: It
  23.  * reads bytes and translates them into characters according to a specified
  24.  * character encoding.  The encoding that it uses may be specified by name, or
  25.  * the platform's default encoding may be accepted.
  26.  *
  27.  * <p> Each invocation of one of an InputStreamReader's read() methods may
  28.  * cause one or more bytes to be read from the underlying byte-input stream.
  29.  * For top efficiency, consider wrapping an InputStreamReader within a
  30.  * BufferedReader; for example,
  31.  *
  32.  * <pre>
  33.  * BufferedReader in
  34.  *   = new BufferedReader(new InputStreamReader(System.in));
  35.  * </pre>
  36.  *
  37.  * @see BufferedReader
  38.  * @see InputStream
  39.  *
  40.  * @version     1.13, 98/07/01
  41.  * @author    Mark Reinhold
  42.  * @since    JDK1.1
  43.  */
  44.  
  45. public class InputStreamReader extends Reader {
  46.  
  47.     private ByteToCharConverter btc;
  48.     private InputStream in;
  49.  
  50.     private static final int defaultByteBufferSize = 8192;
  51.     private byte bb[];        /* Input buffer */
  52.  
  53.     /**
  54.      * Create an InputStreamReader that uses the default character encoding.
  55.      *
  56.      * @param  in   An InputStream
  57.      */
  58.     public InputStreamReader(InputStream in) {
  59.     this(in, ByteToCharConverter.getDefault());
  60.     }
  61.  
  62.     /**
  63.      * Create an InputStreamReader that uses the named character encoding.
  64.      *
  65.      * @param  in   An InputStream
  66.      * @param  enc  Name of encoding to be used
  67.      *
  68.      * @exception  UnsupportedEncodingException
  69.      *             If the named encoding is not supported
  70.      */
  71.     public InputStreamReader(InputStream in, String enc)
  72.     throws UnsupportedEncodingException
  73.     {
  74.     this(in, ByteToCharConverter.getConverter(enc));
  75.     }
  76.  
  77.     /**
  78.      * Create an InputStreamReader that uses the specified byte-to-character
  79.      * converter.  The converter is assumed to have been reset.
  80.      *
  81.      * @param  in   An InputStream
  82.      * @param  btc  A ByteToCharConverter
  83.      */
  84.     private InputStreamReader(InputStream in, ByteToCharConverter btc) {
  85.     super(in);
  86.     this.in = in;
  87.     this.btc = btc;
  88.     bb = new byte[defaultByteBufferSize];
  89.     }
  90.  
  91.     /**
  92.      * Return the name of the encoding being used by this stream.  May return
  93.      * null if the stream has been closed.
  94.      */
  95.     public String getEncoding() {
  96.     synchronized (lock) {
  97.         if (btc != null)
  98.         return btc.getCharacterEncoding();
  99.         else
  100.         return null;
  101.     }
  102.     }
  103.  
  104.  
  105.     /* Buffer handling */
  106.  
  107.     private int nBytes = 0;    /* -1 implies EOF has been reached */
  108.     private int nextByte = 0;
  109.  
  110.     private void malfunction() {
  111.     throw new InternalError("Converter malfunction (" +
  112.                 btc.getCharacterEncoding() +
  113.                 ") -- please submit a bug report via " +
  114.                 System.getProperty("java.vendor.url.bug"));
  115.     }
  116.  
  117.     private int convertInto(char cbuf[], int off, int end) throws IOException {
  118.     int nc = 0;
  119.     if (nextByte < nBytes) {
  120.         try {
  121.         nc = btc.convert(bb, nextByte, nBytes,
  122.                  cbuf, off, end);
  123.         nextByte = nBytes;
  124.         if (btc.nextByteIndex() != nextByte)
  125.             malfunction();
  126.         }
  127.         catch (ConversionBufferFullException x) {
  128.         nextByte = btc.nextByteIndex();
  129.         nc = btc.nextCharIndex() - off;
  130.         }
  131.     }
  132.     return nc;
  133.     }
  134.  
  135.     private int flushInto(char cbuf[], int off, int end) throws IOException {
  136.     int nc = 0;
  137.     try {
  138.         nc = btc.flush(cbuf, off, end);
  139.     }
  140.     catch (ConversionBufferFullException x) {
  141.         nc = btc.nextCharIndex() - off;
  142.     }
  143.     return nc;
  144.     }
  145.  
  146.     private int fill(char cbuf[], int off, int end) throws IOException {
  147.     int nc = 0;
  148.  
  149.     if (nextByte < nBytes)
  150.         nc = convertInto(cbuf, off, end);
  151.  
  152.     while (off + nc < end) {
  153.  
  154.         if (nBytes != -1) {
  155.         if ((nc > 0) && !inReady())
  156.             break;    /* Block at most once */
  157.         nBytes = in.read(bb);
  158.         }
  159.  
  160.         if (nBytes == -1) {
  161.         nc += flushInto(cbuf, off + nc, end);
  162.         if (nc == 0)
  163.             return -1;
  164.         else
  165.             break;
  166.         }
  167.         else {
  168.         nextByte = 0;
  169.         nc += convertInto(cbuf, off + nc, end);
  170.         }
  171.     }
  172.  
  173.     return nc;
  174.     }
  175.  
  176.     /**
  177.      * Tell whether the underlying byte stream is ready to be read.  Return
  178.      * false for those streams that do not support available(), such as the
  179.      * Win32 console stream.
  180.      */
  181.     private boolean inReady() {
  182.     try {
  183.         return in.available() > 0;
  184.     } catch (IOException x) {
  185.         return false;
  186.     }
  187.     }
  188.  
  189.  
  190.     /** Check to make sure that the stream has not been closed */
  191.     private void ensureOpen() throws IOException {
  192.     if (in == null)
  193.         throw new IOException("Stream closed");
  194.     }
  195.  
  196.     /**
  197.      * Read a single character.
  198.      *
  199.      * @return The character read, or -1 if the end of the stream has been
  200.      *         reached
  201.      *
  202.      * @exception  IOException  If an I/O error occurs
  203.      */
  204.     public int read() throws IOException {
  205.     char cb[] = new char[1];
  206.     if (read(cb, 0, 1) == -1)
  207.         return -1;
  208.     else
  209.         return cb[0];
  210.     }
  211.  
  212.     /**
  213.      * Read characters into a portion of an array.
  214.      *
  215.      * @param      cbuf  Destination buffer
  216.      * @param      off   Offset at which to start storing characters
  217.      * @param      len   Maximum number of characters to read
  218.      *
  219.      * @return     The number of characters read, or -1 if the end of the stream
  220.      *             has been reached
  221.      *
  222.      * @exception  IOException  If an I/O error occurs
  223.      */
  224.     public int read(char cbuf[], int off, int len) throws IOException {
  225.     synchronized (lock) {
  226.         ensureOpen();
  227.         return fill(cbuf, off, off + len);
  228.     }
  229.     }
  230.  
  231.     /**
  232.      * Tell whether this stream is ready to be read.  An InputStreamReader is
  233.      * ready if its input buffer is not empty, or if bytes are available to be
  234.      * read from the underlying byte stream.
  235.      *
  236.      * @exception  IOException  If an I/O error occurs
  237.      */
  238.     public boolean ready() throws IOException {
  239.     synchronized (lock) {
  240.         ensureOpen();
  241.         return (nextByte < nBytes) || inReady();
  242.     }
  243.     }
  244.  
  245.     /**
  246.      * Close the stream.
  247.      *
  248.      * @exception  IOException  If an I/O error occurs
  249.      */
  250.     public void close() throws IOException {
  251.     synchronized (lock) {
  252.         if (in == null)
  253.         return;
  254.         in.close();
  255.         in = null;
  256.         bb = null;
  257.         btc = null;
  258.     }
  259.     }
  260.  
  261. }
  262.