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

  1. /*
  2.  * @(#)OutputStreamWriter.java    1.11 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.CharToByteConverter;
  18. import sun.io.ConversionBufferFullException;
  19.  
  20.  
  21. /**
  22.  * Write characters to an output stream, translating characters into bytes
  23.  * according to a specified character encoding.  Each OutputStreamWriter
  24.  * incorporates its own CharToByteConverter, and is thus a bridge from
  25.  * character streams to byte streams.
  26.  *
  27.  * <p> The encoding used by an OutputStreamWriter may be specified by name, by
  28.  * providing a CharToByteConverter, or by accepting the default encoding, which
  29.  * is defined by the system property <tt>file.encoding</tt>.
  30.  *
  31.  * <p> Each invocation of a write() method causes the encoding converter to be
  32.  * invoked on the given character(s).  The resulting bytes are accumulated in a
  33.  * buffer before being written to the underlying output stream.  The size of
  34.  * this buffer may be specified, but by default it is large enough for most
  35.  * purposes.  Note that the characters passed to the write() methods are not
  36.  * buffered.  For top efficiency, consider wrapping an OutputStreamWriter
  37.  * within a BufferedWriter so as to avoid frequent converter invocations.  For
  38.  * example,
  39.  *
  40.  * <pre>
  41.  * Writer out
  42.  *   = new BufferedWriter(new OutputStreamWriter(System.out));
  43.  * </pre>
  44.  *
  45.  * @see BufferedWriter
  46.  * @see OutputStream
  47.  *
  48.  * @version     1.10, 97/01/27
  49.  * @author    Mark Reinhold
  50.  * @since    JDK1.1
  51.  */
  52.  
  53. public class OutputStreamWriter extends Writer {
  54.  
  55.     private CharToByteConverter ctb;
  56.     private OutputStream out;
  57.  
  58.     private static final int defaultByteBufferSize = 8192;
  59.     private byte bb[];
  60.     private int nextByte = 0;
  61.     private int nBytes = 0;
  62.  
  63.     /**
  64.      * Create an OutputStreamWriter that uses the named character encoding.
  65.      *
  66.      * @param  out  An OutputStream
  67.      * @param  enc  Name of the encoding to be used
  68.      *
  69.      * @exception  UnsupportedEncodingException
  70.      *             If the named encoding is not supported
  71.      */
  72.     public OutputStreamWriter(OutputStream out, String enc)
  73.     throws UnsupportedEncodingException
  74.     {
  75.     this(out, CharToByteConverter.getConverter(enc));
  76.     }
  77.  
  78.     /**
  79.      * Create an OutputStreamWriter that uses the default character encoding.
  80.      *
  81.      * @param  out  An OutputStream
  82.      */
  83.     public OutputStreamWriter(OutputStream out) {
  84.     this(out, CharToByteConverter.getDefault());
  85.     }
  86.  
  87.     /**
  88.      * Create an OutputStreamWriter that uses the specified character-to-byte
  89.      * converter.  The converter is assumed to have been reset.
  90.      *
  91.      * @param  out  An OutputStream
  92.      * @param  ctb  A CharToByteConverter
  93.      */
  94.     private OutputStreamWriter(OutputStream out, CharToByteConverter ctb) {
  95.     super(out);
  96.     this.out = out;
  97.     this.ctb = ctb;
  98.     bb = new byte[defaultByteBufferSize];
  99.     nBytes = defaultByteBufferSize;
  100.     }
  101.  
  102.     /**
  103.      * Return the name of the encoding being used by this stream.  May return
  104.      * null if the stream has been closed.
  105.      */
  106.     public String getEncoding() {
  107.     synchronized (lock) {
  108.         if (ctb != null)
  109.         return ctb.getCharacterEncoding();
  110.         else
  111.         return null;
  112.     }
  113.     }
  114.  
  115.     /** Check to make sure that the stream has not been closed */
  116.     private void ensureOpen() throws IOException {
  117.     if (out == null)
  118.         throw new IOException("Stream closed");
  119.     }
  120.  
  121.     /**
  122.      * Write a single character.
  123.      *
  124.      * @exception  IOException  If an I/O error occurs
  125.      */
  126.     public void write(int c) throws IOException {
  127.     char cbuf[] = new char[1];
  128.     cbuf[0] = (char) c;
  129.     write(cbuf, 0, 1);
  130.     }
  131.  
  132.     /**
  133.      * Write a portion of an array of characters.
  134.      *
  135.      * @param  cbuf  Buffer of characters
  136.      * @param  off   Offset from which to start writing characters
  137.      * @param  len   Number of characters to write
  138.      *
  139.      * @exception  IOException  If an I/O error occurs
  140.      */
  141.     public void write(char cbuf[], int off, int len) throws IOException {
  142.     synchronized (lock) {
  143.         ensureOpen();
  144.  
  145.         int ci = off, end = off + len;
  146.         while (ci < end) {
  147.         boolean bufferFull = false;
  148.  
  149.         try {
  150.             nextByte += ctb.convert(cbuf, ci, end,
  151.                         bb, nextByte, nBytes);
  152.             ci = end;
  153.         }
  154.         catch (ConversionBufferFullException x) {
  155.             int nci = ctb.nextCharIndex();
  156.             if (nci == ci) {
  157.             /* Buffer doesn't even hold one character */
  158.             throw new CharConversionException("Output buffer too small");
  159.             }
  160.             ci = nci;
  161.             bufferFull = true;
  162.             nextByte = ctb.nextByteIndex();
  163.         }
  164.  
  165.         if ((nextByte >= nBytes) || bufferFull) {
  166.             out.write(bb, 0, nextByte);
  167.             nextByte = 0;
  168.         }
  169.         }
  170.     }
  171.     }
  172.  
  173.     /**
  174.      * Write a portion of a string.
  175.      *
  176.      * @param  str  A String
  177.      * @param  off  Offset from which to start writing characters
  178.      * @param  len  Number of characters to write
  179.      *
  180.      * @exception  IOException  If an I/O error occurs
  181.      */
  182.     public void write(String str, int off, int len) throws IOException {
  183.     char cbuf[] = new char[len];
  184.     str.getChars(off, off + len, cbuf, 0);
  185.     write(cbuf, 0, len);
  186.     }
  187.  
  188.     /**
  189.      * Flush the output buffer to the underlying byte stream, without flushing
  190.      * the byte stream itself.  This method is non-private only so that it may
  191.      * be invoked by PrintStream.
  192.      */
  193.     void flushBuffer() throws IOException {
  194.     synchronized (lock) {
  195.         ensureOpen();
  196.  
  197.         for (;;) {
  198.         try {
  199.             nextByte += ctb.flush(bb, nextByte, nBytes);
  200.         }
  201.         catch (ConversionBufferFullException x) {
  202.             nextByte = ctb.nextByteIndex();
  203.         }
  204.         if (nextByte == 0)
  205.             break;
  206.         if (nextByte > 0) {
  207.             out.write(bb, 0, nextByte);
  208.             nextByte = 0;
  209.         }
  210.         }
  211.     }
  212.     }
  213.  
  214.     /**
  215.      * Flush the stream.
  216.      *
  217.      * @exception  IOException  If an I/O error occurs
  218.      */
  219.     public void flush() throws IOException {
  220.     synchronized (lock) {
  221.         flushBuffer();
  222.         out.flush();
  223.     }
  224.     }
  225.  
  226.     /**
  227.      * Close the stream.
  228.      *
  229.      * @exception  IOException  If an I/O error occurs
  230.      */
  231.     public void close() throws IOException {
  232.     synchronized (lock) {
  233.         if (out == null)
  234.         return;
  235.         flush();
  236.         out.close();
  237.         out = null;
  238.         bb = null;
  239.         ctb = null;
  240.     }
  241.     }
  242.  
  243. }
  244.