001: /*
002: * Copyright 1994-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package java.io;
027:
028: /**
029: * A <code>ByteArrayInputStream</code> contains
030: * an internal buffer that contains bytes that
031: * may be read from the stream. An internal
032: * counter keeps track of the next byte to
033: * be supplied by the <code>read</code> method.
034: * <p>
035: * Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
036: * this class can be called after the stream has been closed without
037: * generating an <tt>IOException</tt>.
038: *
039: * @author Arthur van Hoff
040: * @version 1.53, 05/05/07
041: * @see java.io.StringBufferInputStream
042: * @since JDK1.0
043: */
044: public class ByteArrayInputStream extends InputStream {
045:
046: /**
047: * An array of bytes that was provided
048: * by the creator of the stream. Elements <code>buf[0]</code>
049: * through <code>buf[count-1]</code> are the
050: * only bytes that can ever be read from the
051: * stream; element <code>buf[pos]</code> is
052: * the next byte to be read.
053: */
054: protected byte buf[];
055:
056: /**
057: * The index of the next character to read from the input stream buffer.
058: * This value should always be nonnegative
059: * and not larger than the value of <code>count</code>.
060: * The next byte to be read from the input stream buffer
061: * will be <code>buf[pos]</code>.
062: */
063: protected int pos;
064:
065: /**
066: * The currently marked position in the stream.
067: * ByteArrayInputStream objects are marked at position zero by
068: * default when constructed. They may be marked at another
069: * position within the buffer by the <code>mark()</code> method.
070: * The current buffer position is set to this point by the
071: * <code>reset()</code> method.
072: * <p>
073: * If no mark has been set, then the value of mark is the offset
074: * passed to the constructor (or 0 if the offset was not supplied).
075: *
076: * @since JDK1.1
077: */
078: protected int mark = 0;
079:
080: /**
081: * The index one greater than the last valid character in the input
082: * stream buffer.
083: * This value should always be nonnegative
084: * and not larger than the length of <code>buf</code>.
085: * It is one greater than the position of
086: * the last byte within <code>buf</code> that
087: * can ever be read from the input stream buffer.
088: */
089: protected int count;
090:
091: /**
092: * Creates a <code>ByteArrayInputStream</code>
093: * so that it uses <code>buf</code> as its
094: * buffer array.
095: * The buffer array is not copied.
096: * The initial value of <code>pos</code>
097: * is <code>0</code> and the initial value
098: * of <code>count</code> is the length of
099: * <code>buf</code>.
100: *
101: * @param buf the input buffer.
102: */
103: public ByteArrayInputStream(byte buf[]) {
104: this .buf = buf;
105: this .pos = 0;
106: this .count = buf.length;
107: }
108:
109: /**
110: * Creates <code>ByteArrayInputStream</code>
111: * that uses <code>buf</code> as its
112: * buffer array. The initial value of <code>pos</code>
113: * is <code>offset</code> and the initial value
114: * of <code>count</code> is the minimum of <code>offset+length</code>
115: * and <code>buf.length</code>.
116: * The buffer array is not copied. The buffer's mark is
117: * set to the specified offset.
118: *
119: * @param buf the input buffer.
120: * @param offset the offset in the buffer of the first byte to read.
121: * @param length the maximum number of bytes to read from the buffer.
122: */
123: public ByteArrayInputStream(byte buf[], int offset, int length) {
124: this .buf = buf;
125: this .pos = offset;
126: this .count = Math.min(offset + length, buf.length);
127: this .mark = offset;
128: }
129:
130: /**
131: * Reads the next byte of data from this input stream. The value
132: * byte is returned as an <code>int</code> in the range
133: * <code>0</code> to <code>255</code>. If no byte is available
134: * because the end of the stream has been reached, the value
135: * <code>-1</code> is returned.
136: * <p>
137: * This <code>read</code> method
138: * cannot block.
139: *
140: * @return the next byte of data, or <code>-1</code> if the end of the
141: * stream has been reached.
142: */
143: public synchronized int read() {
144: return (pos < count) ? (buf[pos++] & 0xff) : -1;
145: }
146:
147: /**
148: * Reads up to <code>len</code> bytes of data into an array of bytes
149: * from this input stream.
150: * If <code>pos</code> equals <code>count</code>,
151: * then <code>-1</code> is returned to indicate
152: * end of file. Otherwise, the number <code>k</code>
153: * of bytes read is equal to the smaller of
154: * <code>len</code> and <code>count-pos</code>.
155: * If <code>k</code> is positive, then bytes
156: * <code>buf[pos]</code> through <code>buf[pos+k-1]</code>
157: * are copied into <code>b[off]</code> through
158: * <code>b[off+k-1]</code> in the manner performed
159: * by <code>System.arraycopy</code>. The
160: * value <code>k</code> is added into <code>pos</code>
161: * and <code>k</code> is returned.
162: * <p>
163: * This <code>read</code> method cannot block.
164: *
165: * @param b the buffer into which the data is read.
166: * @param off the start offset in the destination array <code>b</code>
167: * @param len the maximum number of bytes read.
168: * @return the total number of bytes read into the buffer, or
169: * <code>-1</code> if there is no more data because the end of
170: * the stream has been reached.
171: * @exception NullPointerException If <code>b</code> is <code>null</code>.
172: * @exception IndexOutOfBoundsException If <code>off</code> is negative,
173: * <code>len</code> is negative, or <code>len</code> is greater than
174: * <code>b.length - off</code>
175: */
176: public synchronized int read(byte b[], int off, int len) {
177: if (b == null) {
178: throw new NullPointerException();
179: } else if (off < 0 || len < 0 || len > b.length - off) {
180: throw new IndexOutOfBoundsException();
181: }
182: if (pos >= count) {
183: return -1;
184: }
185: if (pos + len > count) {
186: len = count - pos;
187: }
188: if (len <= 0) {
189: return 0;
190: }
191: System.arraycopy(buf, pos, b, off, len);
192: pos += len;
193: return len;
194: }
195:
196: /**
197: * Skips <code>n</code> bytes of input from this input stream. Fewer
198: * bytes might be skipped if the end of the input stream is reached.
199: * The actual number <code>k</code>
200: * of bytes to be skipped is equal to the smaller
201: * of <code>n</code> and <code>count-pos</code>.
202: * The value <code>k</code> is added into <code>pos</code>
203: * and <code>k</code> is returned.
204: *
205: * @param n the number of bytes to be skipped.
206: * @return the actual number of bytes skipped.
207: */
208: public synchronized long skip(long n) {
209: if (pos + n > count) {
210: n = count - pos;
211: }
212: if (n < 0) {
213: return 0;
214: }
215: pos += n;
216: return n;
217: }
218:
219: /**
220: * Returns the number of remaining bytes that can be read (or skipped over)
221: * from this input stream.
222: * <p>
223: * The value returned is <code>count - pos</code>,
224: * which is the number of bytes remaining to be read from the input buffer.
225: *
226: * @return the number of remaining bytes that can be read (or skipped
227: * over) from this input stream without blocking.
228: */
229: public synchronized int available() {
230: return count - pos;
231: }
232:
233: /**
234: * Tests if this <code>InputStream</code> supports mark/reset. The
235: * <code>markSupported</code> method of <code>ByteArrayInputStream</code>
236: * always returns <code>true</code>.
237: *
238: * @since JDK1.1
239: */
240: public boolean markSupported() {
241: return true;
242: }
243:
244: /**
245: * Set the current marked position in the stream.
246: * ByteArrayInputStream objects are marked at position zero by
247: * default when constructed. They may be marked at another
248: * position within the buffer by this method.
249: * <p>
250: * If no mark has been set, then the value of the mark is the
251: * offset passed to the constructor (or 0 if the offset was not
252: * supplied).
253: *
254: * <p> Note: The <code>readAheadLimit</code> for this class
255: * has no meaning.
256: *
257: * @since JDK1.1
258: */
259: public void mark(int readAheadLimit) {
260: mark = pos;
261: }
262:
263: /**
264: * Resets the buffer to the marked position. The marked position
265: * is 0 unless another position was marked or an offset was specified
266: * in the constructor.
267: */
268: public synchronized void reset() {
269: pos = mark;
270: }
271:
272: /**
273: * Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
274: * this class can be called after the stream has been closed without
275: * generating an <tt>IOException</tt>.
276: * <p>
277: */
278: public void close() throws IOException {
279: }
280:
281: }
|