1. /*
  2. * @(#)ByteArrayOutputStream.java 1.40 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.io;
  8. /**
  9. * This class implements an output stream in which the data is
  10. * written into a byte array. The buffer automatically grows as data
  11. * is written to it.
  12. * The data can be retrieved using <code>toByteArray()</code> and
  13. * <code>toString()</code>.
  14. *
  15. * @author Arthur van Hoff
  16. * @version 1.27, 10/20/97
  17. * @since JDK1.0
  18. */
  19. public class ByteArrayOutputStream extends OutputStream {
  20. /**
  21. * The buffer where data is stored.
  22. */
  23. protected byte buf[];
  24. /**
  25. * The number of valid bytes in the buffer.
  26. */
  27. protected int count;
  28. /**
  29. * Flag indicating whether the stream has been closed.
  30. */
  31. private boolean isClosed = false;
  32. /** Check to make sure that the stream has not been closed */
  33. private void ensureOpen() {
  34. /* This method does nothing for now. Once we add throws clauses
  35. * to the I/O methods in this class, it will throw an IOException
  36. * if the stream has been closed.
  37. */
  38. }
  39. /**
  40. * Creates a new byte array output stream. The buffer capacity is
  41. * initially 32 bytes, though its size increases if necessary.
  42. */
  43. public ByteArrayOutputStream() {
  44. this(32);
  45. }
  46. /**
  47. * Creates a new byte array output stream, with a buffer capacity of
  48. * the specified size, in bytes.
  49. *
  50. * @param size the initial size.
  51. * @exception IllegalArgumentException if size is negative.
  52. */
  53. public ByteArrayOutputStream(int size) {
  54. if (size < 0) {
  55. throw new IllegalArgumentException("Negative initial size: "
  56. + size);
  57. }
  58. buf = new byte[size];
  59. }
  60. /**
  61. * Writes the specified byte to this byte array output stream.
  62. *
  63. * @param b the byte to be written.
  64. */
  65. public synchronized void write(int b) {
  66. ensureOpen();
  67. int newcount = count + 1;
  68. if (newcount > buf.length) {
  69. byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
  70. System.arraycopy(buf, 0, newbuf, 0, count);
  71. buf = newbuf;
  72. }
  73. buf[count] = (byte)b;
  74. count = newcount;
  75. }
  76. /**
  77. * Writes <code>len</code> bytes from the specified byte array
  78. * starting at offset <code>off</code> to this byte array output stream.
  79. *
  80. * @param b the data.
  81. * @param off the start offset in the data.
  82. * @param len the number of bytes to write.
  83. */
  84. public synchronized void write(byte b[], int off, int len) {
  85. ensureOpen();
  86. if ((off < 0) || (off > b.length) || (len < 0) ||
  87. ((off + len) > b.length) || ((off + len) < 0)) {
  88. throw new IndexOutOfBoundsException();
  89. } else if (len == 0) {
  90. return;
  91. }
  92. int newcount = count + len;
  93. if (newcount > buf.length) {
  94. byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
  95. System.arraycopy(buf, 0, newbuf, 0, count);
  96. buf = newbuf;
  97. }
  98. System.arraycopy(b, off, buf, count, len);
  99. count = newcount;
  100. }
  101. /**
  102. * Writes the complete contents of this byte array output stream to
  103. * the specified output stream argument, as if by calling the output
  104. * stream's write method using <code>out.write(buf, 0, count)</code>.
  105. *
  106. * @param out the output stream to which to write the data.
  107. * @exception IOException if an I/O error occurs.
  108. */
  109. public synchronized void writeTo(OutputStream out) throws IOException {
  110. out.write(buf, 0, count);
  111. }
  112. /**
  113. * Resets the <code>count</code> field of this byte array output
  114. * stream to zero, so that all currently accumulated output in the
  115. * ouput stream is discarded. The output stream can be used again,
  116. * reusing the already allocated buffer space.
  117. *
  118. * @see java.io.ByteArrayInputStream#count
  119. */
  120. public synchronized void reset() {
  121. ensureOpen();
  122. count = 0;
  123. }
  124. /**
  125. * Creates a newly allocated byte array. Its size is the current
  126. * size of this output stream and the valid contents of the buffer
  127. * have been copied into it.
  128. *
  129. * @return the current contents of this output stream, as a byte array.
  130. * @see java.io.ByteArrayOutputStream#size()
  131. */
  132. public synchronized byte toByteArray()[] {
  133. byte newbuf[] = new byte[count];
  134. System.arraycopy(buf, 0, newbuf, 0, count);
  135. return newbuf;
  136. }
  137. /**
  138. * Returns the current size of the buffer.
  139. *
  140. * @return the value of the <code>count</code> field, which is the number
  141. * of valid bytes in this output stream.
  142. * @see java.io.ByteArrayOutputStream#count
  143. */
  144. public int size() {
  145. return count;
  146. }
  147. /**
  148. * Converts the buffer's contents into a string, translating bytes into
  149. * characters according to the platform's default character encoding.
  150. */
  151. public String toString() {
  152. return new String(buf, 0, count);
  153. }
  154. /**
  155. * Converts the buffer's contents into a string, translating bytes into
  156. * characters according to the specified character encoding.
  157. *
  158. * @param enc a character-encoding name.
  159. * @since JDK1.1
  160. */
  161. public String toString(String enc) throws UnsupportedEncodingException {
  162. return new String(buf, 0, count, enc);
  163. }
  164. /**
  165. * Creates a newly allocated string. Its size is the current size of
  166. * the output stream and the valid contents of the buffer have been
  167. * copied into it. Each character <i>c</i> in the resulting string is
  168. * constructed from the corresponding element <i>b</i> in the byte
  169. * array such that:
  170. * <blockquote><pre>
  171. * c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))
  172. * </pre></blockquote>
  173. *
  174. * @deprecated This method does not properly convert bytes into characters.
  175. * As of JDK 1.1, the preferred way to do this is via the
  176. * <code>toString(String enc)</code> method, which takes an encoding-name
  177. * argument, or the <code>toString()</code> method, which uses the
  178. * platform's default character encoding.
  179. *
  180. * @param hibyte the high byte of each resulting Unicode character.
  181. * @return the current contents of the output stream, as a string.
  182. * @see java.io.ByteArrayOutputStream#size()
  183. * @see java.io.ByteArrayOutputStream#toString(String)
  184. * @see java.io.ByteArrayOutputStream#toString()
  185. */
  186. public String toString(int hibyte) {
  187. return new String(buf, hibyte, 0, count);
  188. }
  189. /**
  190. * Closes this output stream and releases any system resources
  191. * associated with this stream. A closed stream cannot perform
  192. * output operations and cannot be reopened.
  193. * <p>
  194. *
  195. */
  196. public synchronized void close() throws IOException {
  197. isClosed = true;
  198. }
  199. }