1 /*
2 * Copyright (c) 1994, 2018, 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.nio.charset.Charset;
29 import java.util.Arrays;
30 import java.util.Objects;
31
32 /**
33 * This class implements an output stream in which the data is
34 * written into a byte array. The buffer automatically grows as data
35 * is written to it.
36 * The data can be retrieved using {@code toByteArray()} and
37 * {@code toString()}.
38 * <p>
39 * Closing a {@code ByteArrayOutputStream} has no effect. The methods in
40 * this class can be called after the stream has been closed without
41 * generating an {@code IOException}.
42 *
43 * @author Arthur van Hoff
44 * @since 1.0
45 */
46
47 public class ByteArrayOutputStream extends OutputStream {
48
49 /**
50 * The buffer where data is stored.
51 */
67 /**
68 * Creates a new {@code ByteArrayOutputStream}, with a buffer capacity of
69 * the specified size, in bytes.
70 *
71 * @param size the initial size.
72 * @throws IllegalArgumentException if size is negative.
73 */
74 public ByteArrayOutputStream(int size) {
75 if (size < 0) {
76 throw new IllegalArgumentException("Negative initial size: "
77 + size);
78 }
79 buf = new byte[size];
80 }
81
82 /**
83 * Increases the capacity if necessary to ensure that it can hold
84 * at least the number of elements specified by the minimum
85 * capacity argument.
86 *
87 * @param minCapacity the desired minimum capacity
88 * @throws OutOfMemoryError if {@code minCapacity < 0}. This is
89 * interpreted as a request for the unsatisfiably large capacity
90 * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
91 */
92 private void ensureCapacity(int minCapacity) {
93 // overflow-conscious code
94 if (minCapacity - buf.length > 0)
95 grow(minCapacity);
96 }
97
98 /**
99 * The maximum size of array to allocate.
100 * Some VMs reserve some header words in an array.
101 * Attempts to allocate larger arrays may result in
102 * OutOfMemoryError: Requested array size exceeds VM limit
103 */
104 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
105
106 /**
107 * Increases the capacity to ensure that it can hold at least the
108 * number of elements specified by the minimum capacity argument.
109 *
110 * @param minCapacity the desired minimum capacity
111 */
112 private void grow(int minCapacity) {
113 // overflow-conscious code
114 int oldCapacity = buf.length;
115 int newCapacity = oldCapacity << 1;
116 if (newCapacity - minCapacity < 0)
117 newCapacity = minCapacity;
118 if (newCapacity - MAX_ARRAY_SIZE > 0)
119 newCapacity = hugeCapacity(minCapacity);
120 buf = Arrays.copyOf(buf, newCapacity);
121 }
122
123 private static int hugeCapacity(int minCapacity) {
124 if (minCapacity < 0) // overflow
125 throw new OutOfMemoryError();
126 return (minCapacity > MAX_ARRAY_SIZE) ?
127 Integer.MAX_VALUE :
128 MAX_ARRAY_SIZE;
129 }
130
131 /**
132 * Writes the specified byte to this {@code ByteArrayOutputStream}.
133 *
134 * @param b the byte to be written.
135 */
136 public synchronized void write(int b) {
137 ensureCapacity(count + 1);
138 buf[count] = (byte) b;
139 count += 1;
140 }
141
142 /**
143 * Writes {@code len} bytes from the specified byte array
144 * starting at offset {@code off} to this {@code ByteArrayOutputStream}.
145 *
146 * @param b the data.
147 * @param off the start offset in the data.
148 * @param len the number of bytes to write.
|
1 /*
2 * Copyright (c) 1994, 2019, 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.nio.charset.Charset;
29 import java.util.Arrays;
30 import java.util.Objects;
31
32 import jdk.internal.util.ArraysSupport;
33
34 /**
35 * This class implements an output stream in which the data is
36 * written into a byte array. The buffer automatically grows as data
37 * is written to it.
38 * The data can be retrieved using {@code toByteArray()} and
39 * {@code toString()}.
40 * <p>
41 * Closing a {@code ByteArrayOutputStream} has no effect. The methods in
42 * this class can be called after the stream has been closed without
43 * generating an {@code IOException}.
44 *
45 * @author Arthur van Hoff
46 * @since 1.0
47 */
48
49 public class ByteArrayOutputStream extends OutputStream {
50
51 /**
52 * The buffer where data is stored.
53 */
69 /**
70 * Creates a new {@code ByteArrayOutputStream}, with a buffer capacity of
71 * the specified size, in bytes.
72 *
73 * @param size the initial size.
74 * @throws IllegalArgumentException if size is negative.
75 */
76 public ByteArrayOutputStream(int size) {
77 if (size < 0) {
78 throw new IllegalArgumentException("Negative initial size: "
79 + size);
80 }
81 buf = new byte[size];
82 }
83
84 /**
85 * Increases the capacity if necessary to ensure that it can hold
86 * at least the number of elements specified by the minimum
87 * capacity argument.
88 *
89 * @param minCapacity the desired minimum capacity.
90 * @throws OutOfMemoryError if {@code minCapacity < 0} and
91 * {@code minCapacity - buf.length > 0}. This is interpreted as a
92 * request for the unsatisfiably large capacity.
93 * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
94 */
95 private void ensureCapacity(int minCapacity) {
96 // overflow-conscious code
97 int oldCapacity = buf.length;
98 int minGrowth = minCapacity - oldCapacity;
99 if (minGrowth > 0) {
100 buf = Arrays.copyOf(buf, ArraysSupport.calcLength(oldCapacity,
101 minGrowth, oldCapacity /* preferred growth */));
102 }
103 }
104
105 /**
106 * Writes the specified byte to this {@code ByteArrayOutputStream}.
107 *
108 * @param b the byte to be written.
109 */
110 public synchronized void write(int b) {
111 ensureCapacity(count + 1);
112 buf[count] = (byte) b;
113 count += 1;
114 }
115
116 /**
117 * Writes {@code len} bytes from the specified byte array
118 * starting at offset {@code off} to this {@code ByteArrayOutputStream}.
119 *
120 * @param b the data.
121 * @param off the start offset in the data.
122 * @param len the number of bytes to write.
|