New test
[official-gcc.git] / libjava / java / io / BufferedInputStream.java
blob698abf608af5c68e3b0bd84a40eca1276da9ebb6
1 /* Copyright (C) 1998, 1999 Cygnus Solutions
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
7 details. */
9 package java.io;
11 /**
12 * @author Warren Levy <warrenl@cygnus.com>
13 * @date October 8, 1998.
15 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
16 * "The Java Language Specification", ISBN 0-201-63451-1
17 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
18 * Status: Believed complete and correct.
21 public class BufferedInputStream extends FilterInputStream
23 /* Internal buffer array for data. */
24 protected byte[] buf;
26 /* Index one greater than the last valid byte in the buffer. */
27 protected int count = 0;
29 /* The current position in the buffer. */
30 protected int pos = 0;
32 /* The value of pos the last time mark() was called. */
33 protected int markpos = -1;
35 /* The maximum read-ahead allowed before calls to reset() fail. */
36 protected int marklimit = 0;
38 public BufferedInputStream(InputStream in)
40 this(in, 2048);
43 public BufferedInputStream(InputStream in, int size)
45 super(in);
46 if (size <= 0)
47 throw new IllegalArgumentException();
48 buf = new byte[size];
51 public synchronized int available() throws IOException
53 return count - pos + super.available();
56 public void close() throws IOException
58 // Free up the array memory.
59 buf = null;
60 super.close();
63 public synchronized void mark(int readlimit)
65 marklimit = readlimit;
66 markpos = pos;
69 public boolean markSupported()
71 return true;
74 public synchronized int read() throws IOException
76 if (pos >= count && !refill())
77 return -1; // EOF
79 if (markpos >= 0 && pos - markpos > marklimit)
80 markpos = -1;
82 return ((int) buf[pos++]) & 0xFF;
85 public synchronized int read(byte[] b, int off, int len) throws IOException
87 if (off < 0 || len < 0 || off + len > b.length)
88 throw new ArrayIndexOutOfBoundsException();
90 if (pos >= count && !refill())
91 return -1; // No bytes were read before EOF.
93 int remain = Math.min(count - pos, len);
94 System.arraycopy(buf, pos, b, off, remain);
95 pos += remain;
97 if (markpos >= 0 && pos - markpos > marklimit)
98 markpos = -1;
100 return remain;
103 public synchronized void reset() throws IOException
105 if (markpos < 0)
106 throw new IOException();
108 pos = markpos;
111 public synchronized long skip(long n) throws IOException
113 final long origN = n;
115 while (n > 0L)
117 if (pos >= count && !refill())
118 if (n < origN)
119 break;
120 else
121 return -1; // No bytes were read before EOF.
123 int numread = (int) Math.min((long) (count - pos), n);
124 pos += numread;
125 n -= numread;
127 if (markpos >= 0 && pos - markpos > marklimit)
128 markpos = -1;
131 return origN - n;
134 private boolean refill() throws IOException
136 if (markpos < 0)
137 count = pos = 0;
138 else if (markpos > 0)
140 // Shift the marked bytes (if any) to the beginning of the array
141 // but don't grow it. This saves space in case a reset is done
142 // before we reach the max capacity of this array.
143 System.arraycopy(buf, markpos, buf, 0, count - markpos);
144 count -= markpos;
145 pos -= markpos;
146 markpos = 0;
148 else if (marklimit >= buf.length) // BTW, markpos == 0
150 // Need to grow the buffer now to have room for marklimit bytes.
151 // Note that the new buffer is one greater than marklimit.
152 // This is so that there will be one byte past marklimit to be read
153 // before having to call refill again, thus allowing marklimit to be
154 // invalidated. That way refill doesn't have to check marklimit.
155 byte[] newbuf = new byte[marklimit + 1];
156 System.arraycopy(buf, 0, newbuf, 0, count);
157 buf = newbuf;
160 int numread = super.read(buf, count, buf.length - count);
162 if (numread < 0) // EOF
163 return false;
165 count += numread;
166 return true;