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