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