Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/io/ByteArrayOutputStream.java
38829 views
/*1* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.io;2627import java.util.Arrays;2829/**30* This class implements an output stream in which the data is31* written into a byte array. The buffer automatically grows as data32* is written to it.33* The data can be retrieved using <code>toByteArray()</code> and34* <code>toString()</code>.35* <p>36* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in37* this class can be called after the stream has been closed without38* generating an <tt>IOException</tt>.39*40* @author Arthur van Hoff41* @since JDK1.042*/4344public class ByteArrayOutputStream extends OutputStream {4546/**47* The buffer where data is stored.48*/49protected byte buf[];5051/**52* The number of valid bytes in the buffer.53*/54protected int count;5556/**57* Creates a new byte array output stream. The buffer capacity is58* initially 32 bytes, though its size increases if necessary.59*/60public ByteArrayOutputStream() {61this(32);62}6364/**65* Creates a new byte array output stream, with a buffer capacity of66* the specified size, in bytes.67*68* @param size the initial size.69* @exception IllegalArgumentException if size is negative.70*/71public ByteArrayOutputStream(int size) {72if (size < 0) {73throw new IllegalArgumentException("Negative initial size: "74+ size);75}76buf = new byte[size];77}7879/**80* Increases the capacity if necessary to ensure that it can hold81* at least the number of elements specified by the minimum82* capacity argument.83*84* @param minCapacity the desired minimum capacity85* @throws OutOfMemoryError if {@code minCapacity < 0}. This is86* interpreted as a request for the unsatisfiably large capacity87* {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.88*/89private void ensureCapacity(int minCapacity) {90// overflow-conscious code91if (minCapacity - buf.length > 0)92grow(minCapacity);93}9495/**96* The maximum size of array to allocate.97* Some VMs reserve some header words in an array.98* Attempts to allocate larger arrays may result in99* OutOfMemoryError: Requested array size exceeds VM limit100*/101private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;102103/**104* Increases the capacity to ensure that it can hold at least the105* number of elements specified by the minimum capacity argument.106*107* @param minCapacity the desired minimum capacity108*/109private void grow(int minCapacity) {110// overflow-conscious code111int oldCapacity = buf.length;112int newCapacity = oldCapacity << 1;113if (newCapacity - minCapacity < 0)114newCapacity = minCapacity;115if (newCapacity - MAX_ARRAY_SIZE > 0)116newCapacity = hugeCapacity(minCapacity);117buf = Arrays.copyOf(buf, newCapacity);118}119120private static int hugeCapacity(int minCapacity) {121if (minCapacity < 0) // overflow122throw new OutOfMemoryError();123return (minCapacity > MAX_ARRAY_SIZE) ?124Integer.MAX_VALUE :125MAX_ARRAY_SIZE;126}127128/**129* Writes the specified byte to this byte array output stream.130*131* @param b the byte to be written.132*/133public synchronized void write(int b) {134ensureCapacity(count + 1);135buf[count] = (byte) b;136count += 1;137}138139/**140* Writes <code>len</code> bytes from the specified byte array141* starting at offset <code>off</code> to this byte array output stream.142*143* @param b the data.144* @param off the start offset in the data.145* @param len the number of bytes to write.146*/147public synchronized void write(byte b[], int off, int len) {148if ((off < 0) || (off > b.length) || (len < 0) ||149((off + len) - b.length > 0)) {150throw new IndexOutOfBoundsException();151}152ensureCapacity(count + len);153System.arraycopy(b, off, buf, count, len);154count += len;155}156157/**158* Writes the complete contents of this byte array output stream to159* the specified output stream argument, as if by calling the output160* stream's write method using <code>out.write(buf, 0, count)</code>.161*162* @param out the output stream to which to write the data.163* @exception IOException if an I/O error occurs.164*/165public synchronized void writeTo(OutputStream out) throws IOException {166out.write(buf, 0, count);167}168169/**170* Resets the <code>count</code> field of this byte array output171* stream to zero, so that all currently accumulated output in the172* output stream is discarded. The output stream can be used again,173* reusing the already allocated buffer space.174*175* @see java.io.ByteArrayInputStream#count176*/177public synchronized void reset() {178count = 0;179}180181/**182* Creates a newly allocated byte array. Its size is the current183* size of this output stream and the valid contents of the buffer184* have been copied into it.185*186* @return the current contents of this output stream, as a byte array.187* @see java.io.ByteArrayOutputStream#size()188*/189public synchronized byte toByteArray()[] {190return Arrays.copyOf(buf, count);191}192193/**194* Returns the current size of the buffer.195*196* @return the value of the <code>count</code> field, which is the number197* of valid bytes in this output stream.198* @see java.io.ByteArrayOutputStream#count199*/200public synchronized int size() {201return count;202}203204/**205* Converts the buffer's contents into a string decoding bytes using the206* platform's default character set. The length of the new <tt>String</tt>207* is a function of the character set, and hence may not be equal to the208* size of the buffer.209*210* <p> This method always replaces malformed-input and unmappable-character211* sequences with the default replacement string for the platform's212* default character set. The {@linkplain java.nio.charset.CharsetDecoder}213* class should be used when more control over the decoding process is214* required.215*216* @return String decoded from the buffer's contents.217* @since JDK1.1218*/219public synchronized String toString() {220return new String(buf, 0, count);221}222223/**224* Converts the buffer's contents into a string by decoding the bytes using225* the named {@link java.nio.charset.Charset charset}. The length of the new226* <tt>String</tt> is a function of the charset, and hence may not be equal227* to the length of the byte array.228*229* <p> This method always replaces malformed-input and unmappable-character230* sequences with this charset's default replacement string. The {@link231* java.nio.charset.CharsetDecoder} class should be used when more control232* over the decoding process is required.233*234* @param charsetName the name of a supported235* {@link java.nio.charset.Charset charset}236* @return String decoded from the buffer's contents.237* @exception UnsupportedEncodingException238* If the named charset is not supported239* @since JDK1.1240*/241public synchronized String toString(String charsetName)242throws UnsupportedEncodingException243{244return new String(buf, 0, count, charsetName);245}246247/**248* Creates a newly allocated string. Its size is the current size of249* the output stream and the valid contents of the buffer have been250* copied into it. Each character <i>c</i> in the resulting string is251* constructed from the corresponding element <i>b</i> in the byte252* array such that:253* <blockquote><pre>254* c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))255* </pre></blockquote>256*257* @deprecated This method does not properly convert bytes into characters.258* As of JDK 1.1, the preferred way to do this is via the259* <code>toString(String enc)</code> method, which takes an encoding-name260* argument, or the <code>toString()</code> method, which uses the261* platform's default character encoding.262*263* @param hibyte the high byte of each resulting Unicode character.264* @return the current contents of the output stream, as a string.265* @see java.io.ByteArrayOutputStream#size()266* @see java.io.ByteArrayOutputStream#toString(String)267* @see java.io.ByteArrayOutputStream#toString()268*/269@Deprecated270public synchronized String toString(int hibyte) {271return new String(buf, hibyte, 0, count);272}273274/**275* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in276* this class can be called after the stream has been closed without277* generating an <tt>IOException</tt>.278*/279public void close() throws IOException {280}281282}283284285