emul/compact/src/main/java/java/io/ByteArrayOutputStream.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 06 Feb 2013 15:07:20 +0100
branchjdk7-b147
changeset 682 5d25a1df3540
permissions -rw-r--r--
More useful classes
     1 /*
     2  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package java.io;
    27 
    28 import java.util.Arrays;
    29 
    30 /**
    31  * This class implements an output stream in which the data is
    32  * written into a byte array. The buffer automatically grows as data
    33  * is written to it.
    34  * The data can be retrieved using <code>toByteArray()</code> and
    35  * <code>toString()</code>.
    36  * <p>
    37  * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
    38  * this class can be called after the stream has been closed without
    39  * generating an <tt>IOException</tt>.
    40  *
    41  * @author  Arthur van Hoff
    42  * @since   JDK1.0
    43  */
    44 
    45 public class ByteArrayOutputStream extends OutputStream {
    46 
    47     /**
    48      * The buffer where data is stored.
    49      */
    50     protected byte buf[];
    51 
    52     /**
    53      * The number of valid bytes in the buffer.
    54      */
    55     protected int count;
    56 
    57     /**
    58      * Creates a new byte array output stream. The buffer capacity is
    59      * initially 32 bytes, though its size increases if necessary.
    60      */
    61     public ByteArrayOutputStream() {
    62         this(32);
    63     }
    64 
    65     /**
    66      * Creates a new byte array output stream, with a buffer capacity of
    67      * the specified size, in bytes.
    68      *
    69      * @param   size   the initial size.
    70      * @exception  IllegalArgumentException if size is negative.
    71      */
    72     public ByteArrayOutputStream(int size) {
    73         if (size < 0) {
    74             throw new IllegalArgumentException("Negative initial size: "
    75                                                + size);
    76         }
    77         buf = new byte[size];
    78     }
    79 
    80     /**
    81      * Increases the capacity if necessary to ensure that it can hold
    82      * at least the number of elements specified by the minimum
    83      * capacity argument.
    84      *
    85      * @param minCapacity the desired minimum capacity
    86      * @throws OutOfMemoryError if {@code minCapacity < 0}.  This is
    87      * interpreted as a request for the unsatisfiably large capacity
    88      * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
    89      */
    90     private void ensureCapacity(int minCapacity) {
    91         // overflow-conscious code
    92         if (minCapacity - buf.length > 0)
    93             grow(minCapacity);
    94     }
    95 
    96     /**
    97      * Increases the capacity to ensure that it can hold at least the
    98      * number of elements specified by the minimum capacity argument.
    99      *
   100      * @param minCapacity the desired minimum capacity
   101      */
   102     private void grow(int minCapacity) {
   103         // overflow-conscious code
   104         int oldCapacity = buf.length;
   105         int newCapacity = oldCapacity << 1;
   106         if (newCapacity - minCapacity < 0)
   107             newCapacity = minCapacity;
   108         if (newCapacity < 0) {
   109             if (minCapacity < 0) // overflow
   110                 throw new OutOfMemoryError();
   111             newCapacity = Integer.MAX_VALUE;
   112         }
   113         buf = Arrays.copyOf(buf, newCapacity);
   114     }
   115 
   116     /**
   117      * Writes the specified byte to this byte array output stream.
   118      *
   119      * @param   b   the byte to be written.
   120      */
   121     public synchronized void write(int b) {
   122         ensureCapacity(count + 1);
   123         buf[count] = (byte) b;
   124         count += 1;
   125     }
   126 
   127     /**
   128      * Writes <code>len</code> bytes from the specified byte array
   129      * starting at offset <code>off</code> to this byte array output stream.
   130      *
   131      * @param   b     the data.
   132      * @param   off   the start offset in the data.
   133      * @param   len   the number of bytes to write.
   134      */
   135     public synchronized void write(byte b[], int off, int len) {
   136         if ((off < 0) || (off > b.length) || (len < 0) ||
   137             ((off + len) - b.length > 0)) {
   138             throw new IndexOutOfBoundsException();
   139         }
   140         ensureCapacity(count + len);
   141         System.arraycopy(b, off, buf, count, len);
   142         count += len;
   143     }
   144 
   145     /**
   146      * Writes the complete contents of this byte array output stream to
   147      * the specified output stream argument, as if by calling the output
   148      * stream's write method using <code>out.write(buf, 0, count)</code>.
   149      *
   150      * @param      out   the output stream to which to write the data.
   151      * @exception  IOException  if an I/O error occurs.
   152      */
   153     public synchronized void writeTo(OutputStream out) throws IOException {
   154         out.write(buf, 0, count);
   155     }
   156 
   157     /**
   158      * Resets the <code>count</code> field of this byte array output
   159      * stream to zero, so that all currently accumulated output in the
   160      * output stream is discarded. The output stream can be used again,
   161      * reusing the already allocated buffer space.
   162      *
   163      * @see     java.io.ByteArrayInputStream#count
   164      */
   165     public synchronized void reset() {
   166         count = 0;
   167     }
   168 
   169     /**
   170      * Creates a newly allocated byte array. Its size is the current
   171      * size of this output stream and the valid contents of the buffer
   172      * have been copied into it.
   173      *
   174      * @return  the current contents of this output stream, as a byte array.
   175      * @see     java.io.ByteArrayOutputStream#size()
   176      */
   177     public synchronized byte toByteArray()[] {
   178         return Arrays.copyOf(buf, count);
   179     }
   180 
   181     /**
   182      * Returns the current size of the buffer.
   183      *
   184      * @return  the value of the <code>count</code> field, which is the number
   185      *          of valid bytes in this output stream.
   186      * @see     java.io.ByteArrayOutputStream#count
   187      */
   188     public synchronized int size() {
   189         return count;
   190     }
   191 
   192     /**
   193      * Converts the buffer's contents into a string decoding bytes using the
   194      * platform's default character set. The length of the new <tt>String</tt>
   195      * is a function of the character set, and hence may not be equal to the
   196      * size of the buffer.
   197      *
   198      * <p> This method always replaces malformed-input and unmappable-character
   199      * sequences with the default replacement string for the platform's
   200      * default character set. The {@linkplain java.nio.charset.CharsetDecoder}
   201      * class should be used when more control over the decoding process is
   202      * required.
   203      *
   204      * @return String decoded from the buffer's contents.
   205      * @since  JDK1.1
   206      */
   207     public synchronized String toString() {
   208         return new String(buf, 0, count);
   209     }
   210 
   211     /**
   212      * Converts the buffer's contents into a string by decoding the bytes using
   213      * the specified {@link java.nio.charset.Charset charsetName}. The length of
   214      * the new <tt>String</tt> is a function of the charset, and hence may not be
   215      * equal to the length of the byte array.
   216      *
   217      * <p> This method always replaces malformed-input and unmappable-character
   218      * sequences with this charset's default replacement string. The {@link
   219      * java.nio.charset.CharsetDecoder} class should be used when more control
   220      * over the decoding process is required.
   221      *
   222      * @param  charsetName  the name of a supported
   223      *              {@linkplain java.nio.charset.Charset </code>charset<code>}
   224      * @return String decoded from the buffer's contents.
   225      * @exception  UnsupportedEncodingException
   226      *             If the named charset is not supported
   227      * @since   JDK1.1
   228      */
   229     public synchronized String toString(String charsetName)
   230         throws UnsupportedEncodingException
   231     {
   232         return new String(buf, 0, count, charsetName);
   233     }
   234 
   235     /**
   236      * Creates a newly allocated string. Its size is the current size of
   237      * the output stream and the valid contents of the buffer have been
   238      * copied into it. Each character <i>c</i> in the resulting string is
   239      * constructed from the corresponding element <i>b</i> in the byte
   240      * array such that:
   241      * <blockquote><pre>
   242      *     c == (char)(((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
   243      * </pre></blockquote>
   244      *
   245      * @deprecated This method does not properly convert bytes into characters.
   246      * As of JDK&nbsp;1.1, the preferred way to do this is via the
   247      * <code>toString(String enc)</code> method, which takes an encoding-name
   248      * argument, or the <code>toString()</code> method, which uses the
   249      * platform's default character encoding.
   250      *
   251      * @param      hibyte    the high byte of each resulting Unicode character.
   252      * @return     the current contents of the output stream, as a string.
   253      * @see        java.io.ByteArrayOutputStream#size()
   254      * @see        java.io.ByteArrayOutputStream#toString(String)
   255      * @see        java.io.ByteArrayOutputStream#toString()
   256      */
   257     @Deprecated
   258     public synchronized String toString(int hibyte) {
   259         return new String(buf, hibyte, 0, count);
   260     }
   261 
   262     /**
   263      * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
   264      * this class can be called after the stream has been closed without
   265      * generating an <tt>IOException</tt>.
   266      * <p>
   267      *
   268      */
   269     public void close() throws IOException {
   270     }
   271 
   272 }