001    /* BufferedReader.java
002       Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005
003       Free Software Foundation, Inc.
004    
005    This file is part of GNU Classpath.
006    
007    GNU Classpath is free software; you can redistribute it and/or modify
008    it under the terms of the GNU General Public License as published by
009    the Free Software Foundation; either version 2, or (at your option)
010    any later version.
011    
012    GNU Classpath is distributed in the hope that it will be useful, but
013    WITHOUT ANY WARRANTY; without even the implied warranty of
014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015    General Public License for more details.
016    
017    You should have received a copy of the GNU General Public License
018    along with GNU Classpath; see the file COPYING.  If not, write to the
019    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
020    02110-1301 USA.
021    
022    Linking this library statically or dynamically with other modules is
023    making a combined work based on this library.  Thus, the terms and
024    conditions of the GNU General Public License cover the whole
025    combination.
026    
027    As a special exception, the copyright holders of this library give you
028    permission to link this library with independent modules to produce an
029    executable, regardless of the license terms of these independent
030    modules, and to copy and distribute the resulting executable under
031    terms of your choice, provided that you also meet, for each linked
032    independent module, the terms and conditions of the license of that
033    module.  An independent module is a module which is not derived from
034    or based on this library.  If you modify this library, you may extend
035    this exception to your version of the library, but you are not
036    obligated to do so.  If you do not wish to do so, delete this
037    exception statement from your version. */
038    
039    
040    package java.io;
041    
042    /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
043     * "The Java Language Specification", ISBN 0-201-63451-1
044     * Status:  Complete to version 1.1.
045     */
046    
047    /**
048      * This class allows data to be written to a byte array buffer and
049      * and then retrieved by an application.   The internal byte array
050      * buffer is dynamically resized to hold all the data written.  Please
051      * be aware that writing large amounts to data to this stream will
052      * cause large amounts of memory to be allocated.
053      * <p>
054      * The size of the internal buffer defaults to 32 and it is resized
055      * by doubling the size of the buffer.  This default size can be
056      * overridden by using the
057      * <code>gnu.java.io.ByteArrayOutputStream.initialBufferSize</code>
058      * property.
059      * <p>
060      * There is a constructor that specified the initial buffer size and
061      * that is the preferred way to set that value because it it portable
062      * across all Java class library implementations.
063      * <p>
064      * Note that this class also has methods that convert the byte array
065      * buffer to a <code>String</code> using either the system default or an
066      * application specified character encoding.  Thus it can handle
067      * multibyte character encodings.
068      *
069      * @author Aaron M. Renn (arenn@urbanophile.com)
070      * @author Tom Tromey (tromey@cygnus.com)
071      * @date September 24, 1998
072      */
073    public class ByteArrayOutputStream extends OutputStream
074    {
075      /**
076       * This method initializes a new <code>ByteArrayOutputStream</code>
077       * with the default buffer size of 32 bytes.  If a different initial
078       * buffer size is desired, see the constructor
079       * <code>ByteArrayOutputStream(int size)</code>.  For applications
080       * where the source code is not available, the default buffer size
081       * can be set using the system property
082       * <code>gnu.java.io.ByteArrayOutputStream.initialBufferSize</code>
083       */
084      public ByteArrayOutputStream ()
085      {
086        this (initial_buffer_size);
087      }
088    
089      /**
090       * This method initializes a new <code>ByteArrayOutputStream</code> with
091       * a specified initial buffer size.
092       *
093       * @param size The initial buffer size in bytes
094       */
095      public ByteArrayOutputStream (int size)
096      {
097        buf = new byte[size];
098        count = 0;
099      }
100    
101      /**
102       * This method discards all of the bytes that have been written to
103       * the internal buffer so far by setting the <code>count</code>
104       * variable to 0.  The internal buffer remains at its currently
105       * allocated size.
106       */
107      public synchronized void reset ()
108      {
109        count = 0;
110      }
111    
112      /**
113       * This method returns the number of bytes that have been written to
114       * the buffer so far.  This is the same as the value of the protected
115       * <code>count</code> variable.  If the <code>reset</code> method is
116       * called, then this value is reset as well.  Note that this method does
117       * not return the length of the internal buffer, but only the number
118       * of bytes that have been written to it.
119       *
120       * @return The number of bytes in the internal buffer
121       *
122       * @see #reset()
123       */
124      public int size ()
125      {
126        return count;
127      }
128    
129      /**
130       * This method returns a byte array containing the bytes that have been
131       * written to this stream so far.  This array is a copy of the valid
132       * bytes in the internal buffer and its length is equal to the number of
133       * valid bytes, not necessarily to the the length of the current
134       * internal buffer.  Note that since this method allocates a new array,
135       * it should be used with caution when the internal buffer is very large.
136       */
137      public synchronized byte[] toByteArray ()
138      {
139        byte[] ret = new byte[count];
140        System.arraycopy(buf, 0, ret, 0, count);
141        return ret;
142      }
143    
144      /**
145       * Returns the bytes in the internal array as a <code>String</code>.  The
146       * bytes in the buffer are converted to characters using the system default
147       * encoding.  There is an overloaded <code>toString()</code> method that
148       * allows an application specified character encoding to be used.
149       *
150       * @return A <code>String</code> containing the data written to this
151       * stream so far
152       */
153      public String toString ()
154      {
155        return new String (buf, 0, count);
156      }
157    
158      /**
159       * Returns the bytes in the internal array as a <code>String</code>.  The
160       * bytes in the buffer are converted to characters using the specified
161       * encoding.
162       *
163       * @param enc The name of the character encoding to use
164       *
165       * @return A <code>String</code> containing the data written to this
166       * stream so far
167       *
168       * @exception UnsupportedEncodingException If the named encoding is
169       * not available
170       */
171      public String toString (String enc) throws UnsupportedEncodingException
172      {
173        return new String (buf, 0, count, enc);
174      }
175    
176      /**
177       * This method returns the bytes in the internal array as a
178       * <code>String</code>.  It uses each byte in the array as the low
179       * order eight bits of the Unicode character value and the passed in
180       * parameter as the high eight bits.
181       * <p>
182       * This method does not convert bytes to characters in the proper way and
183       * so is deprecated in favor of the other overloaded <code>toString</code>
184       * methods which use a true character encoding.
185       *
186       * @param hibyte The high eight bits to use for each character in
187       * the <code>String</code>
188       *
189       * @return A <code>String</code> containing the data written to this
190       * stream so far
191       *
192       * @deprecated
193       */
194      public String toString (int hibyte)
195      {
196        return new String (buf, hibyte, 0, count);
197      }
198    
199      // Resize buffer to accommodate new bytes.
200      private void resize (int add)
201      {
202        if (count + add > buf.length)
203          {
204            int newlen = buf.length * 2;
205            if (count + add > newlen)
206              newlen = count + add;
207            byte[] newbuf = new byte[newlen];
208            System.arraycopy(buf, 0, newbuf, 0, count);
209            buf = newbuf;
210          }
211      }
212    
213      /**
214       * This method writes the writes the specified byte into the internal
215       * buffer.
216       *
217       * @param oneByte The byte to be read passed as an int
218       */
219      public synchronized void write (int oneByte)
220      {
221        resize (1);
222        buf[count++] = (byte) oneByte;
223      }
224    
225      /**
226       * This method writes <code>len</code> bytes from the passed in array
227       * <code>buf</code> starting at index <code>offset</code> into the
228       * internal buffer.
229       *
230       * @param buffer The byte array to write data from
231       * @param offset The index into the buffer to start writing data from
232       * @param add The number of bytes to write
233       */
234      public synchronized void write (byte[] buffer, int offset, int add)
235      {
236        // If ADD < 0 then arraycopy will throw the appropriate error for
237        // us.
238        if (add >= 0)
239          resize (add);
240        System.arraycopy(buffer, offset, buf, count, add);
241        count += add;
242      }
243    
244      /**
245       * This method writes all the bytes that have been written to this stream
246       * from the internal buffer to the specified <code>OutputStream</code>.
247       *
248       * @param out The <code>OutputStream</code> to write to
249       *
250       * @exception IOException If an error occurs
251       */
252      public synchronized void writeTo (OutputStream out) throws IOException
253      {
254        out.write(buf, 0, count);
255      }
256    
257      /**
258       * The internal buffer where the data written is stored
259       */
260      protected byte[] buf;
261    
262      /**
263       * The number of bytes that have been written to the buffer
264       */
265      protected int count;
266    
267      /**
268       * The default initial buffer size.  Specified by the JCL.
269       */
270      private static final int DEFAULT_INITIAL_BUFFER_SIZE = 32;
271    
272      // The default buffer size which can be overridden by the user.
273      private static final int initial_buffer_size;
274    
275      static
276      {
277        int r
278          = Integer.getInteger ("gnu.java.io.ByteArrayOutputStream.initialBufferSize",
279                                DEFAULT_INITIAL_BUFFER_SIZE).intValue ();
280        if (r <= 0)
281          r = DEFAULT_INITIAL_BUFFER_SIZE;
282        initial_buffer_size = r;
283      }
284    }