aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/io/BufferedInputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/io/BufferedInputStream.java')
-rw-r--r--libjava/java/io/BufferedInputStream.java168
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;
+ }
+}