adding a test case
[IRC.git] / Robust / src / ClassLibrary / SSJavaInfer / ByteArrayInputStream.java
1 /* ByteArrayInputStream.java -- Read an array as a stream
2    Copyright (C) 1998, 1999, 2001, 2005  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 //package java.io;
39
40 /**
41  * This class permits an array of bytes to be read as an input stream.
42  * 
43  * @author Warren Levy (warrenl@cygnus.com)
44  * @author Aaron M. Renn (arenn@urbanophile.com)
45  */
46
47 public class ByteArrayInputStream extends InputStream {
48   /**
49    * The array that contains the data supplied during read operations
50    */
51   protected byte[] buf;
52
53   /**
54    * The array index of the next byte to be read from the buffer
55    * <code>buf</code>
56    */
57   protected int pos;
58
59   /**
60    * The currently marked position in the stream. This defaults to 0, so a reset
61    * operation on the stream resets it to read from array index 0 in the buffer
62    * - even if the stream was initially created with an offset greater than 0
63    */
64   protected int mark;
65
66   /**
67    * This indicates the maximum number of bytes that can be read from this
68    * stream. It is the array index of the position after the last valid byte in
69    * the buffer <code>buf</code>
70    */
71   protected int count;
72
73   /**
74    * Create a new ByteArrayInputStream that will read bytes from the passed in
75    * byte array. This stream will read from the beginning to the end of the
76    * array. It is identical to calling an overloaded constructor as
77    * <code>ByteArrayInputStream(buf, 0, buf.length)</code>.
78    * <p>
79    * Note that this array is not copied. If its contents are changed while this
80    * stream is being read, those changes will be reflected in the bytes supplied
81    * to the reader. Please use caution in changing the contents of the buffer
82    * while this stream is open.
83    * 
84    * @param buffer
85    *          The byte array buffer this stream will read from.
86    */
87   public ByteArrayInputStream(byte[] buffer) {
88     this(buffer, 0, buffer.length);
89   }
90
91   /**
92    * Create a new ByteArrayInputStream that will read bytes from the passed in
93    * byte array. This stream will read from position <code>offset</code> in the
94    * array for a length of <code>length</code> bytes past <code>offset</code>.
95    * If the stream is reset to a position before <code>offset</code> then more
96    * than <code>length</code> bytes can be read from the stream. The
97    * <code>length</code> value should be viewed as the array index one greater
98    * than the last position in the buffer to read.
99    * <p>
100    * Note that this array is not copied. If its contents are changed while this
101    * stream is being read, those changes will be reflected in the bytes supplied
102    * to the reader. Please use caution in changing the contents of the buffer
103    * while this stream is open.
104    * 
105    * @param buffer
106    *          The byte array buffer this stream will read from.
107    * @param offset
108    *          The index into the buffer to start reading bytes from
109    * @param length
110    *          The number of bytes to read from the buffer
111    */
112   public ByteArrayInputStream(byte[] buffer, int offset, int length) {
113     if (offset < 0 || length < 0 || offset > buffer.length)
114       throw new IllegalArgumentException();
115
116     buf = buffer;
117
118     count = offset + length;
119     if (count > buf.length)
120       count = buf.length;
121
122     pos = offset;
123     mark = pos;
124   }
125
126   /**
127    * This method returns the number of bytes available to be read from this
128    * stream. The value returned will be equal to <code>count - pos</code>.
129    * 
130    * @return The number of bytes that can be read from this stream before
131    *         blocking, which is all of them
132    */
133   public synchronized int available() {
134     return count - pos;
135   }
136
137   /**
138    * This method sets the mark position in this stream to the current position.
139    * Note that the <code>readlimit</code> parameter in this method does nothing
140    * as this stream is always capable of remembering all the bytes int it.
141    * <p>
142    * Note that in this class the mark position is set by default to position 0
143    * in the stream. This is in constrast to some other stream types where there
144    * is no default mark position.
145    * 
146    * @param readLimit
147    *          The number of bytes this stream must remember. This parameter is
148    *          ignored.
149    */
150   public synchronized void mark(int readLimit) {
151     // readLimit is ignored per Java Class Lib. book, p.220.
152     mark = pos;
153   }
154
155   /**
156    * This method overrides the <code>markSupported</code> method in
157    * <code>InputStream</code> in order to return <code>true</code> - indicating
158    * that this stream class supports mark/reset functionality.
159    * 
160    * @return <code>true</code> to indicate that this class supports mark/reset.
161    */
162   public boolean markSupported() {
163     return true;
164   }
165
166   /**
167    * This method reads one byte from the stream. The <code>pos</code> counter is
168    * advanced to the next byte to be read. The byte read is returned as an int
169    * in the range of 0-255. If the stream position is already at the end of the
170    * buffer, no byte is read and a -1 is returned in order to indicate the end
171    * of the stream.
172    * 
173    * @return The byte read, or -1 if end of stream
174    */
175   public synchronized int read() {
176     if (pos < count)
177       return ((int) buf[pos++]) & 0xFF;
178     return -1;
179   }
180
181   /**
182    * This method reads bytes from the stream and stores them into a caller
183    * supplied buffer. It starts storing the data at index <code>offset</code>
184    * into the buffer and attempts to read <code>len</code> bytes. This method
185    * can return before reading the number of bytes requested if the end of the
186    * stream is encountered first. The actual number of bytes read is returned.
187    * If no bytes can be read because the stream is already at the end of stream
188    * position, a -1 is returned.
189    * <p>
190    * This method does not block.
191    * 
192    * @param buffer
193    *          The array into which the bytes read should be stored.
194    * @param offset
195    *          The offset into the array to start storing bytes
196    * @param length
197    *          The requested number of bytes to read
198    * 
199    * @return The actual number of bytes read, or -1 if end of stream.
200    */
201   public synchronized int read(byte[] buffer, int offset, int length) {
202     if (pos >= count)
203       return -1;
204
205     int numBytes = Math.min(count - pos, length);
206     System.arraycopy(buf, pos, buffer, offset, numBytes);
207     pos += numBytes;
208     return numBytes;
209   }
210
211   /**
212    * This method sets the read position in the stream to the mark point by
213    * setting the <code>pos</code> variable equal to the <code>mark</code>
214    * variable. Since a mark can be set anywhere in the array, the mark/reset
215    * methods int this class can be used to provide random search capabilities
216    * for this type of stream.
217    */
218   public synchronized void reset() {
219     pos = mark;
220   }
221
222   /**
223    * This method attempts to skip the requested number of bytes in the input
224    * stream. It does this by advancing the <code>pos</code> value by the
225    * specified number of bytes. It this would exceed the length of the buffer,
226    * then only enough bytes are skipped to position the stream at the end of the
227    * buffer. The actual number of bytes skipped is returned.
228    * 
229    * @param num
230    *          The requested number of bytes to skip
231    * 
232    * @return The actual number of bytes skipped.
233    */
234   public synchronized long skip(long num) {
235     // Even though the var numBytes is a long, in reality it can never
236     // be larger than an int since the result of subtracting 2 positive
237     // ints will always fit in an int. Since we have to return a long
238     // anyway, numBytes might as well just be a long.
239     long numBytes = Math.min((long) (count - pos), num < 0 ? 0L : num);
240     pos += (int) numBytes;
241     return numBytes;
242   }
243 }