diff options
Diffstat (limited to 'libjava/java/io/BufferedInputStream.java')
-rw-r--r-- | libjava/java/io/BufferedInputStream.java | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/libjava/java/io/BufferedInputStream.java b/libjava/java/io/BufferedInputStream.java new file mode 100644 index 0000000..698abf6 --- /dev/null +++ b/libjava/java/io/BufferedInputStream.java @@ -0,0 +1,168 @@ +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.io; + +/** + * @author Warren Levy <warrenl@cygnus.com> + * @date October 8, 1998. + */ +/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 + * "The Java Language Specification", ISBN 0-201-63451-1 + * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. + * Status: Believed complete and correct. + */ + +public class BufferedInputStream extends FilterInputStream +{ + /* Internal buffer array for data. */ + protected byte[] buf; + + /* Index one greater than the last valid byte in the buffer. */ + protected int count = 0; + + /* The current position in the buffer. */ + protected int pos = 0; + + /* The value of pos the last time mark() was called. */ + protected int markpos = -1; + + /* The maximum read-ahead allowed before calls to reset() fail. */ + protected int marklimit = 0; + + public BufferedInputStream(InputStream in) + { + this(in, 2048); + } + + public BufferedInputStream(InputStream in, int size) + { + super(in); + if (size <= 0) + throw new IllegalArgumentException(); + buf = new byte[size]; + } + + public synchronized int available() throws IOException + { + return count - pos + super.available(); + } + + public void close() throws IOException + { + // Free up the array memory. + buf = null; + super.close(); + } + + public synchronized void mark(int readlimit) + { + marklimit = readlimit; + markpos = pos; + } + + public boolean markSupported() + { + return true; + } + + public synchronized int read() throws IOException + { + if (pos >= count && !refill()) + return -1; // EOF + + if (markpos >= 0 && pos - markpos > marklimit) + markpos = -1; + + return ((int) buf[pos++]) & 0xFF; + } + + public synchronized int read(byte[] b, int off, int len) throws IOException + { + if (off < 0 || len < 0 || off + len > b.length) + throw new ArrayIndexOutOfBoundsException(); + + if (pos >= count && !refill()) + return -1; // No bytes were read before EOF. + + int remain = Math.min(count - pos, len); + System.arraycopy(buf, pos, b, off, remain); + pos += remain; + + if (markpos >= 0 && pos - markpos > marklimit) + markpos = -1; + + return remain; + } + + public synchronized void reset() throws IOException + { + if (markpos < 0) + throw new IOException(); + + pos = markpos; + } + + public synchronized long skip(long n) throws IOException + { + final long origN = n; + + while (n > 0L) + { + if (pos >= count && !refill()) + if (n < origN) + break; + else + return -1; // No bytes were read before EOF. + + int numread = (int) Math.min((long) (count - pos), n); + pos += numread; + n -= numread; + + if (markpos >= 0 && pos - markpos > marklimit) + markpos = -1; + } + + return origN - n; + } + + private boolean refill() throws IOException + { + if (markpos < 0) + count = pos = 0; + else if (markpos > 0) + { + // Shift the marked bytes (if any) to the beginning of the array + // but don't grow it. This saves space in case a reset is done + // before we reach the max capacity of this array. + System.arraycopy(buf, markpos, buf, 0, count - markpos); + count -= markpos; + pos -= markpos; + markpos = 0; + } + else if (marklimit >= buf.length) // BTW, markpos == 0 + { + // Need to grow the buffer now to have room for marklimit bytes. + // Note that the new buffer is one greater than marklimit. + // This is so that there will be one byte past marklimit to be read + // before having to call refill again, thus allowing marklimit to be + // invalidated. That way refill doesn't have to check marklimit. + byte[] newbuf = new byte[marklimit + 1]; + System.arraycopy(buf, 0, newbuf, 0, count); + buf = newbuf; + } + + int numread = super.read(buf, count, buf.length - count); + + if (numread < 0) // EOF + return false; + + count += numread; + return true; + } +} |