This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Fix PR libgcj/20389


Bryce McKinlay wrote:
David Daney wrote:

BufferedInputStream.java from Classpath breaks InputStreamReader.java.

InputStreamReader.java from Classpath breaks because it needs gnu.java.io.decode.Decoder.

We either need to merge much of Classpath, or fix the existing BufferedInputStream.



The Encoder/Decoder mechanisms definitely need to be merged, and I believe this ie being worked on, but thats probably too much change for now.


The appropriate fix for InputStreamReader's dependence on BufferedInputStream will depend on the outcome of that merge.

The Classpath version looks plausible, but I would have to hack on it to make it fit with InputStreamReader.

Your call I guess.



That sounds ok - whatever results in the least diff's against classpath without changing things too radically for 4.0. Would making refill() package-private be sufficient?



The attached patch brings BufferedInputStream over from Classpath with the only changes being that the copyright in Classpath omits 2004 and had refill() being private.


refill has to have default visibility because InputStreamReader does some highly questionable things with it. Since the file was in fact changed in 2004 I thought the copyright should reflect that.

I added the PR testcase to mauve and did make check in libjava and mauve with no regressions on the 4.0.0 branch (i686-pc-linux).

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.

OK to commit to the 4.0 branch and mainline?

David Daney.
Index: java/io/BufferedInputStream.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/BufferedInputStream.java,v
retrieving revision 1.11
diff -u -p -r1.11 BufferedInputStream.java
--- java/io/BufferedInputStream.java	11 Jan 2005 20:04:33 -0000	1.11
+++ java/io/BufferedInputStream.java	9 Mar 2005 19:24:28 -0000
@@ -65,6 +65,7 @@ package java.io;
  */
 public class BufferedInputStream extends FilterInputStream
 {
+
   /**
    * This is the default buffer size
    */
@@ -103,17 +104,11 @@ public class BufferedInputStream extends
   protected int marklimit;
 
   /**
-   * This is the maximum size we have to allocate for the mark buffer.
-   * This number may be huge (Integer.MAX_VALUE). The class will continue
-   * to allocate new chunks (specified by <code>CHUNKSIZE</code>) until the
-   * the size specified by this field is achieved.
-   */
-  private int marktarget = 0;
-
-  /**
-   * This is the number of bytes to allocate to reach marktarget.
+   * This is the initial buffer size. When the buffer is grown because
+   * of marking requirements, it will be grown by bufferSize increments.
+   * The underlying stream will be read in chunks of bufferSize.
    */
-  static final private int CHUNKSIZE = 1024;
+  private final int bufferSize;
 
   /**
    * This method initializes a new <code>BufferedInputStream</code> that will
@@ -143,6 +138,9 @@ public class BufferedInputStream extends
     if (size <= 0)
       throw new IllegalArgumentException();
     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
   {
     // Free up the array memory.
     buf = null;
+    pos = count = 0;
+    markpos = -1;
     super.close();
   }
 
@@ -196,9 +196,7 @@ public class BufferedInputStream extends
    */
   public synchronized void mark(int readlimit)
   {
-    marktarget = marklimit = readlimit;
-    if (marklimit > CHUNKSIZE)
-      marklimit = CHUNKSIZE;
+    marklimit = readlimit;
     markpos = pos;
   }
 
@@ -231,9 +229,6 @@ public class BufferedInputStream extends
     if (pos >= count && !refill())
       return -1;	// EOF
 
-    if (markpos >= 0 && pos - markpos > marktarget)
-      markpos = -1;
-
     return buf[pos++] & 0xFF;
   }
 
@@ -278,9 +273,6 @@ public class BufferedInputStream extends
     off += totalBytesRead;
     len -= totalBytesRead;
 
-    if (markpos >= 0 && pos - markpos > marktarget)
-      markpos = -1;
-
     while (len > 0 && super.available() > 0 && refill())
       {
 	int remain = Math.min(count - pos, len);
@@ -289,9 +281,6 @@ public class BufferedInputStream extends
 	off += remain;
 	len -= remain;
 	totalBytesRead += remain;
-
-	if (markpos >= 0 && pos - markpos > marktarget)
-	  markpos = -1;
       }
 
     return totalBytesRead;
@@ -339,17 +328,11 @@ public class BufferedInputStream extends
     while (n > 0L)
       {
 	if (pos >= count && !refill())
-	  if (n < origN)
-	    break;
-	  else
-	    return 0;	// No bytes were read before EOF.
+          break;
 
 	int numread = (int) Math.min((long) (count - pos), n);
 	pos += numread;
 	n -= numread;
-
-        if (markpos >= 0 && pos - markpos > marktarget)
-          markpos = -1;
       }
 
     return origN - n;
@@ -366,39 +349,31 @@ public class BufferedInputStream extends
     if (buf == null)
       throw new IOException("Stream closed.");
 
-    if (markpos < 0)
-      count = pos = 0;
-    else if (markpos > 0)
+    if (markpos == -1 || count - markpos >= marklimit)
       {
-        // 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;
+	markpos = -1;
+	pos = count = 0;
       }
-    else if (count >= buf.length && count < marktarget)	// BTW, markpos == 0
+    else
       {
-	// 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.
-	marklimit += CHUNKSIZE;
-	if (marklimit >= marktarget)
-	  marklimit = marktarget;
-	byte[] newbuf = new byte[marklimit + 1];
-	System.arraycopy(buf, 0, newbuf, 0, count);
+	byte[] newbuf = buf;
+	if (markpos < bufferSize)
+	  {
+	    newbuf = new byte[count - markpos + bufferSize];
+	  }
+	System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
 	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;
 
     count += numread;
-    return numread > 0;
+    return true;
   }
 }
Index: java/io/InputStreamReader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/InputStreamReader.java,v
retrieving revision 1.18
diff -u -p -r1.18 InputStreamReader.java
--- java/io/InputStreamReader.java	21 Feb 2005 08:27:00 -0000	1.18
+++ java/io/InputStreamReader.java	9 Mar 2005 19:24:28 -0000
@@ -282,11 +282,9 @@ public class InputStreamReader extends R
       {
 	// We have knowledge of the internals of BufferedInputStream
 	// here.  Eww.
-	in.mark (0);
 	// BufferedInputStream.refill() can only be called when
 	// `pos>=count'.
 	boolean r = in.pos < in.count || in.refill ();
-	in.reset ();
 	if (! r)
 	  return -1;
 	converter.setInput(in.buf, in.pos, in.count);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]