home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / InputStreamReader.java < prev    next >
Text File  |  1997-10-27  |  7KB  |  270 lines

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