Commit fc6b4aa4 by David Daney Committed by David Daney

re PR libgcj/20389 (BufferedInputStream gets ArrayIndexOutOfBoundsExeception)

2005-03-09  David Daney  <ddaney@avtrex.com>

	PR libgcj/20389
	Merge BufferedInputStream from GNU Classpath.
	* java/io/BufferedInputStream.java (marktarget): Field removed.
	(CHUNKSIZE): Field removed.
	(bufferSize): New field.
	(BufferedInputStream): Initialize fields.
	(close): Invalidate mark and buffer indexes.
	(mark):  Rewritten.
	(read()): Move mark handling code to refill.
	(read(byte[], int, int)): Ditto.
	(skip): Ditto and simplify EOF testing.
	(refill): Rewritten.
	* java/io/InputStreamReader.java (refill): Removed mark and reset
	of internal BufferedInputStream.

From-SVN: r96217
parent 9c90a97e
2005-03-09 David Daney <ddaney@avtrex.com>
PR libgcj/20389
Merge BufferedInputStream from GNU Classpath.
* java/io/BufferedInputStream.java (marktarget): Field removed.
(CHUNKSIZE): Field removed.
(bufferSize): New field.
(BufferedInputStream): Initialize fields.
(close): Invalidate mark and buffer indexes.
(mark): Rewritten.
(read()): Move mark handling code to refill.
(read(byte[], int, int)): Ditto.
(skip): Ditto and simplify EOF testing.
(refill): Rewritten.
* java/io/InputStreamReader.java (refill): Removed mark and reset
of internal BufferedInputStream.
2005-03-09 Tom Tromey <tromey@redhat.com> 2005-03-09 Tom Tromey <tromey@redhat.com>
* java/lang/natVMClassLoader.cc (defineClass): Reference * java/lang/natVMClassLoader.cc (defineClass): Reference
......
...@@ -65,6 +65,7 @@ package java.io; ...@@ -65,6 +65,7 @@ package java.io;
*/ */
public class BufferedInputStream extends FilterInputStream public class BufferedInputStream extends FilterInputStream
{ {
/** /**
* This is the default buffer size * This is the default buffer size
*/ */
...@@ -103,17 +104,11 @@ public class BufferedInputStream extends FilterInputStream ...@@ -103,17 +104,11 @@ public class BufferedInputStream extends FilterInputStream
protected int marklimit; protected int marklimit;
/** /**
* This is the maximum size we have to allocate for the mark buffer. * This is the initial buffer size. When the buffer is grown because
* This number may be huge (Integer.MAX_VALUE). The class will continue * of marking requirements, it will be grown by bufferSize increments.
* to allocate new chunks (specified by <code>CHUNKSIZE</code>) until the * The underlying stream will be read in chunks of bufferSize.
* the size specified by this field is achieved.
*/
private int marktarget = 0;
/**
* This is the number of bytes to allocate to reach marktarget.
*/ */
static final private int CHUNKSIZE = 1024; private final int bufferSize;
/** /**
* This method initializes a new <code>BufferedInputStream</code> that will * This method initializes a new <code>BufferedInputStream</code> that will
...@@ -143,6 +138,9 @@ public class BufferedInputStream extends FilterInputStream ...@@ -143,6 +138,9 @@ public class BufferedInputStream extends FilterInputStream
if (size <= 0) if (size <= 0)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
buf = new byte[size]; buf = new byte[size];
// initialize pos & count to bufferSize, to prevent refill from
// allocating a new buffer (if the caller starts out by calling mark()).
pos = count = bufferSize = size;
} }
/** /**
...@@ -173,6 +171,8 @@ public class BufferedInputStream extends FilterInputStream ...@@ -173,6 +171,8 @@ public class BufferedInputStream extends FilterInputStream
{ {
// Free up the array memory. // Free up the array memory.
buf = null; buf = null;
pos = count = 0;
markpos = -1;
super.close(); super.close();
} }
...@@ -196,9 +196,7 @@ public class BufferedInputStream extends FilterInputStream ...@@ -196,9 +196,7 @@ public class BufferedInputStream extends FilterInputStream
*/ */
public synchronized void mark(int readlimit) public synchronized void mark(int readlimit)
{ {
marktarget = marklimit = readlimit; marklimit = readlimit;
if (marklimit > CHUNKSIZE)
marklimit = CHUNKSIZE;
markpos = pos; markpos = pos;
} }
...@@ -231,9 +229,6 @@ public class BufferedInputStream extends FilterInputStream ...@@ -231,9 +229,6 @@ public class BufferedInputStream extends FilterInputStream
if (pos >= count && !refill()) if (pos >= count && !refill())
return -1; // EOF return -1; // EOF
if (markpos >= 0 && pos - markpos > marktarget)
markpos = -1;
return buf[pos++] & 0xFF; return buf[pos++] & 0xFF;
} }
...@@ -278,9 +273,6 @@ public class BufferedInputStream extends FilterInputStream ...@@ -278,9 +273,6 @@ public class BufferedInputStream extends FilterInputStream
off += totalBytesRead; off += totalBytesRead;
len -= totalBytesRead; len -= totalBytesRead;
if (markpos >= 0 && pos - markpos > marktarget)
markpos = -1;
while (len > 0 && super.available() > 0 && refill()) while (len > 0 && super.available() > 0 && refill())
{ {
int remain = Math.min(count - pos, len); int remain = Math.min(count - pos, len);
...@@ -289,9 +281,6 @@ public class BufferedInputStream extends FilterInputStream ...@@ -289,9 +281,6 @@ public class BufferedInputStream extends FilterInputStream
off += remain; off += remain;
len -= remain; len -= remain;
totalBytesRead += remain; totalBytesRead += remain;
if (markpos >= 0 && pos - markpos > marktarget)
markpos = -1;
} }
return totalBytesRead; return totalBytesRead;
...@@ -339,22 +328,17 @@ public class BufferedInputStream extends FilterInputStream ...@@ -339,22 +328,17 @@ public class BufferedInputStream extends FilterInputStream
while (n > 0L) while (n > 0L)
{ {
if (pos >= count && !refill()) if (pos >= count && !refill())
if (n < origN) break;
break;
else
return 0; // No bytes were read before EOF.
int numread = (int) Math.min((long) (count - pos), n); int numread = (int) Math.min((long) (count - pos), n);
pos += numread; pos += numread;
n -= numread; n -= numread;
if (markpos >= 0 && pos - markpos > marktarget)
markpos = -1;
} }
return origN - n; return origN - n;
} }
// GCJ LOCAL: package-private for use by InputStreamReader
/** /**
* Called to refill the buffer (when count is equal to pos). * Called to refill the buffer (when count is equal to pos).
* *
...@@ -366,39 +350,31 @@ public class BufferedInputStream extends FilterInputStream ...@@ -366,39 +350,31 @@ public class BufferedInputStream extends FilterInputStream
if (buf == null) if (buf == null)
throw new IOException("Stream closed."); throw new IOException("Stream closed.");
if (markpos < 0) if (markpos == -1 || count - markpos >= marklimit)
count = pos = 0;
else if (markpos > 0)
{ {
// Shift the marked bytes (if any) to the beginning of the array markpos = -1;
// but don't grow it. This saves space in case a reset is done pos = count = 0;
// 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 (count >= buf.length && count < marktarget) // BTW, markpos == 0 else
{ {
// Need to grow the buffer now to have room for marklimit bytes. byte[] newbuf = buf;
// Note that the new buffer is one greater than marklimit. if (markpos < bufferSize)
// 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 newbuf = new byte[count - markpos + bufferSize];
// invalidated. That way refill doesn't have to check marklimit. }
marklimit += CHUNKSIZE; System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
if (marklimit >= marktarget)
marklimit = marktarget;
byte[] newbuf = new byte[marklimit + 1];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf; buf = newbuf;
count -= markpos;
pos -= markpos;
markpos = 0;
} }
int numread = super.read(buf, count, buf.length - count); int numread = super.read(buf, count, bufferSize);
if (numread < 0) // EOF if (numread <= 0) // EOF
return false; return false;
count += numread; count += numread;
return numread > 0; return true;
} }
} }
...@@ -282,11 +282,9 @@ public class InputStreamReader extends Reader ...@@ -282,11 +282,9 @@ public class InputStreamReader extends Reader
{ {
// We have knowledge of the internals of BufferedInputStream // We have knowledge of the internals of BufferedInputStream
// here. Eww. // here. Eww.
in.mark (0);
// BufferedInputStream.refill() can only be called when // BufferedInputStream.refill() can only be called when
// `pos>=count'. // `pos>=count'.
boolean r = in.pos < in.count || in.refill (); boolean r = in.pos < in.count || in.refill ();
in.reset ();
if (! r) if (! r)
return -1; return -1;
converter.setInput(in.buf, in.pos, in.count); converter.setInput(in.buf, in.pos, in.count);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment