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
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. */
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
)
43 public BufferedInputStream(InputStream in
, int size
)
47 throw new IllegalArgumentException();
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.
63 public synchronized void mark(int readlimit
)
65 marklimit
= readlimit
;
69 public boolean markSupported()
74 public synchronized int read() throws IOException
76 if (pos
>= count
&& !refill())
79 if (markpos
>= 0 && pos
- markpos
> marklimit
)
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
);
97 if (markpos
>= 0 && pos
- markpos
> marklimit
)
103 public synchronized void reset() throws IOException
106 throw new IOException();
111 public synchronized long skip(long n
) throws IOException
113 final long origN
= n
;
117 if (pos
>= count
&& !refill())
121 return -1; // No bytes were read before EOF.
123 int numread
= (int) Math
.min((long) (count
- pos
), n
);
127 if (markpos
>= 0 && pos
- markpos
> marklimit
)
134 private boolean refill() throws IOException
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
);
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
);
160 int numread
= super.read(buf
, count
, buf
.length
- count
);
162 if (numread
< 0) // EOF