1. /*
  2. * @(#)ByteArrayInputStream.java 1.33 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. * A <code>ByteArrayInputStream</code> contains
  10. * an internal buffer that contains bytes that
  11. * may be read from the stream. An internal
  12. * counter keeps track of the next byte to
  13. * be supplied by the <code>read</code> method.
  14. *
  15. * @author Arthur van Hoff
  16. * @version 1.33, 11/29/01
  17. * @see java.io.StringBufferInputStream
  18. * @since JDK1.0
  19. */
  20. public
  21. class ByteArrayInputStream extends InputStream {
  22. /**
  23. * A flag that is set to true when this stream is closed.
  24. */
  25. private boolean isClosed = false;
  26. /**
  27. * An array of bytes that was provided
  28. * by the creator of the stream. Elements <code>buf[0]</code>
  29. * through <code>buf[count-1]</code> are the
  30. * only bytes that can ever be read from the
  31. * stream; element <code>buf[pos]</code> is
  32. * the next byte to be read.
  33. */
  34. protected byte buf[];
  35. /**
  36. * The index of the next character to read from the input stream buffer.
  37. * This value should always be nonnegative
  38. * and not larger than the value of <code>count</code>.
  39. * The next byte to be read from the input stream buffer
  40. * will be <code>buf[pos]</code>.
  41. */
  42. protected int pos;
  43. /**
  44. * The currently marked position in the stream.
  45. * ByteArrayInputStream objects are marked at position zero by
  46. * default when constructed. They may be marked at another
  47. * position within the buffer by the <code>mark()</code> method.
  48. * The current buffer position is set to this point by the
  49. * <code>reset()</code> method.
  50. *
  51. * @since JDK1.1
  52. */
  53. protected int mark = 0;
  54. /**
  55. * The index one greater than the last valid character in the input
  56. * stream buffer.
  57. * This value should always be nonnegative
  58. * and not larger than the length of <code>buf</code>.
  59. * It is one greater than the position of
  60. * the last byte within <code>buf</code> that
  61. * can ever be read from the input stream buffer.
  62. */
  63. protected int count;
  64. /**
  65. * Creates a <code>ByteArrayInputStream</code>
  66. * so that it uses <code>buf</code> as its
  67. * buffer array.
  68. * The buffer array is not copied.
  69. * The initial value of <code>pos</code>
  70. * is <code>0</code> and the initial value
  71. * of <code>count</code> is the length of
  72. * <code>buf</code>.
  73. *
  74. * @param buf the input buffer.
  75. */
  76. public ByteArrayInputStream(byte buf[]) {
  77. this.buf = buf;
  78. this.pos = 0;
  79. this.count = buf.length;
  80. }
  81. /**
  82. * Creates <code>ByteArrayInputStream</code>
  83. * that uses <code>buf</code> as its
  84. * buffer array. The initial value of <code>pos</code>
  85. * is <code>offset</code> and the initial value
  86. * of <code>count</code> is <code>offset+len</code>.
  87. * The buffer array is not copied.
  88. * <p>
  89. * Note that if bytes are simply read from
  90. * the resulting input stream, elements <code>buf[pos]</code>
  91. * through <code>buf[pos+len-1]</code> will
  92. * be read; however, if a <code>reset</code>
  93. * operation is performed, then bytes <code>buf[0]</code>
  94. * through b<code>uf[pos-1]</code> will then
  95. * become available for input.
  96. *
  97. * @param buf the input buffer.
  98. * @param offset the offset in the buffer of the first byte to read.
  99. * @param length the maximum number of bytes to read from the buffer.
  100. */
  101. public ByteArrayInputStream(byte buf[], int offset, int length) {
  102. this.buf = buf;
  103. this.pos = offset;
  104. this.count = Math.min(offset + length, buf.length);
  105. this.mark = offset;
  106. }
  107. /**
  108. * Reads the next byte of data from this input stream. The value
  109. * byte is returned as an <code>int</code> in the range
  110. * <code>0</code> to <code>255</code>. If no byte is available
  111. * because the end of the stream has been reached, the value
  112. * <code>-1</code> is returned.
  113. * <p>
  114. * This <code>read</code> method
  115. * cannot block.
  116. *
  117. * @return the next byte of data, or <code>-1</code> if the end of the
  118. * stream has been reached.
  119. */
  120. public synchronized int read() {
  121. ensureOpen();
  122. return (pos < count) ? (buf[pos++] & 0xff) : -1;
  123. }
  124. /**
  125. * Reads up to <code>len</code> bytes of data into an array of bytes
  126. * from this input stream.
  127. * If <code>pos</code> equals <code>count</code>,
  128. * then <code>-1</code> is returned to indicate
  129. * end of file. Otherwise, the number <code>k</code>
  130. * of bytes read is equal to the smaller of
  131. * <code>len</code> and <code>count-pos</code>.
  132. * If <code>k</code> is positive, then bytes
  133. * <code>buf[pos]</code> through <code>buf[pos+k-1]</code>
  134. * are copied into <code>b[off]</code> through
  135. * <code>b[off+k-1]</code> in the manner performed
  136. * by <code>System.arraycopy</code>. The
  137. * value <code>k</code> is added into <code>pos</code>
  138. * and <code>k</code> is returned.
  139. * <p>
  140. * This <code>read</code> method cannot block.
  141. *
  142. * @param b the buffer into which the data is read.
  143. * @param off the start offset of the data.
  144. * @param len the maximum number of bytes read.
  145. * @return the total number of bytes read into the buffer, or
  146. * <code>-1</code> if there is no more data because the end of
  147. * the stream has been reached.
  148. */
  149. public synchronized int read(byte b[], int off, int len) {
  150. ensureOpen();
  151. if (b == null) {
  152. throw new NullPointerException();
  153. } else if ((off < 0) || (off > b.length) || (len < 0) ||
  154. ((off + len) > b.length) || ((off + len) < 0)) {
  155. throw new IndexOutOfBoundsException();
  156. }
  157. if (pos >= count) {
  158. return -1;
  159. }
  160. if (pos + len > count) {
  161. len = count - pos;
  162. }
  163. if (len <= 0) {
  164. return 0;
  165. }
  166. System.arraycopy(buf, pos, b, off, len);
  167. pos += len;
  168. return len;
  169. }
  170. /**
  171. * Skips <code>n</code> bytes of input from this input stream. Fewer
  172. * bytes might be skipped if the end of the input stream is reached.
  173. * The actual number <code>k</code>
  174. * of bytes to be skipped is equal to the smaller
  175. * of <code>n</code> and <code>count-pos</code>.
  176. * The value <code>k</code> is added into <code>pos</code>
  177. * and <code>k</code> is returned.
  178. *
  179. * @param n the number of bytes to be skipped.
  180. * @return the actual number of bytes skipped.
  181. */
  182. public synchronized long skip(long n) {
  183. ensureOpen();
  184. if (pos + n > count) {
  185. n = count - pos;
  186. }
  187. if (n < 0) {
  188. return 0;
  189. }
  190. pos += n;
  191. return n;
  192. }
  193. /**
  194. * Returns the number of bytes that can be read from this input
  195. * stream without blocking.
  196. * The value returned is
  197. * <code>count - pos</code>,
  198. * which is the number of bytes remaining to be read from the input buffer.
  199. *
  200. * @return the number of bytes that can be read from the input stream
  201. * without blocking.
  202. */
  203. public synchronized int available() {
  204. ensureOpen();
  205. return count - pos;
  206. }
  207. /**
  208. * Tests if ByteArrayInputStream supports mark/reset.
  209. *
  210. * @since JDK1.1
  211. */
  212. public boolean markSupported() {
  213. return true;
  214. }
  215. /**
  216. * Set the current marked position in the stream.
  217. * ByteArrayInputStream objects are marked at position zero by
  218. * default when constructed. They may be marked at another
  219. * position within the buffer by this method.
  220. *
  221. * @since JDK1.1
  222. */
  223. public void mark(int readAheadLimit) {
  224. ensureOpen();
  225. mark = pos;
  226. }
  227. /**
  228. * Resets the buffer to the marked position. The marked position
  229. * is the beginning unless another position was marked.
  230. * The value of </code>pos</code> is set to 0.
  231. */
  232. public synchronized void reset() {
  233. ensureOpen();
  234. pos = mark;
  235. }
  236. /**
  237. * Closes this input stream and releases any system resources
  238. * associated with the stream.
  239. * <p>
  240. */
  241. public synchronized void close() throws IOException {
  242. isClosed = true;
  243. }
  244. /** Check to make sure that the stream has not been closed */
  245. private void ensureOpen() {
  246. /* This method does nothing for now. Once we add throws clauses
  247. * to the I/O methods in this class, it will throw an IOException
  248. * if the stream has been closed.
  249. */
  250. }
  251. }