OSDN Git Service

Fix for PR libgcj/3426:
[pf3gnuchains/gcc-fork.git] / libjava / java / io / InputStreamReader.java
index 478d8ef..45fd598 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -44,9 +44,14 @@ public class InputStreamReader extends Reader
 
   private InputStreamReader(InputStream in, BytesToUnicode decoder)
   {
+    // FIXME: someone could pass in a BufferedInputStream whose buffer
+    // is smaller than the longest encoded character for this
+    // encoding.  We will probably go into an infinite loop in this
+    // case.  We probably ought to just have our own byte buffering
+    // here.
     this.in = in instanceof BufferedInputStream
               ? (BufferedInputStream) in
-              : new BufferedInputStream(in, 250);
+              : new BufferedInputStream(in);
     /* Don't need to call super(in) here as long as the lock gets set. */
     this.lock = in;
     converter = decoder;
@@ -71,30 +76,16 @@ public class InputStreamReader extends Reader
   {
     synchronized (lock)
       {
+       if (in == null)
+         throw new IOException("Stream closed");
+
        if (wpos < wcount)
          return true;
-       if (work == null)
-         {
-           work = new char[100];
-           wpos = 0;
-           wcount = 0;
-         }
-       for (;;)
-         {
-           if (in.available() <= 0)
-             return false;
-           in.mark(1);
-           int b = in.read();
-           if (b < 0)
-             return true;
-           in.reset();
-           converter.setInput(in.buf, in.pos, in.count);
-           wpos = 0;
-           wcount = converter.read(work, 0, work.length);
-           in.skip(converter.inpos - in.pos);
-           if (wcount > 0)
-             return true;
-         }
+
+       // According to the spec, an InputStreamReader is ready if its
+       // input buffer is not empty (above), or if bytes are
+       // available on the underlying byte stream.
+       return in.available () > 0;
       }
   }
 
@@ -102,33 +93,26 @@ public class InputStreamReader extends Reader
   {
     synchronized (lock)
       {
+       if (in == null)
+         throw new IOException("Stream closed");
+
+       if (length == 0)
+         return 0;
+
        int wavail = wcount - wpos;
-       if (wavail > 0)
+       if (wavail <= 0)
          {
-           if (length > wavail)
-             length = wavail;
-           System.arraycopy(work, wpos, buf, offset, length);
-           wpos += length;
-           return length;
-         }
-       else
-         {
-           if (length == 0)
-             return 0;
-           for (;;)
-             {
-               in.mark(1);
-               int b = in.read();
-               if (b < 0)
-                 return -1;
-               in.reset();
-               converter.setInput(in.buf, in.pos, in.count);
-               int count = converter.read (buf, offset, length);
-               in.skip(converter.inpos - in.pos);
-               if (count > 0)
-                 return count;
-             }
+           // Nothing waiting, so refill our buffer.
+           if (! refill ())
+             return -1;
+           wavail = wcount - wpos;
          }
+
+       if (length > wavail)
+         length = wavail;
+       System.arraycopy(work, wpos, buf, offset, length);
+       wpos += length;
+       return length;
       }
   }
 
@@ -136,25 +120,47 @@ public class InputStreamReader extends Reader
   {
     synchronized (lock)
       {
+       if (in == null)
+         throw new IOException("Stream closed");
+
        int wavail = wcount - wpos;
-       if (wavail > 0)
-         return work[wpos++];
-       if (work == null)
+       if (wavail <= 0)
          {
-           work = new char[100];
-           wpos = 0;
-           wcount = 0;
+           // Nothing waiting, so refill our buffer.
+           if (! refill ())
+             return -1;
          }
-       else if (wavail == 0)
+
+       return work[wpos++];
+      }
+  }
+
+  // Read more bytes and convert them into the WORK buffer.
+  // Return false on EOF.
+  private boolean refill () throws IOException
+  {
+    wcount = wpos = 0;
+
+    if (work == null)
+      work = new char[100];
+
+    for (;;)
+      {
+       // We have knowledge of the internals of BufferedInputStream
+       // here.  Eww.
+       in.mark (0);
+       boolean r = in.refill ();
+       in.reset ();
+       if (! r)
+         return false;
+       converter.setInput(in.buf, in.pos, in.count);
+       int count = converter.read (work, wpos, work.length - wpos);
+       in.skip(converter.inpos - in.pos);
+       if (count > 0)
          {
-           wpos = 0;
-           wcount = 0;
+           wcount += count;
+           return true;
          }
-       int count = read(work, wpos, work.length-wpos);
-       if (count <= 0)
-         return -1;
-       wcount = wpos + count;
-       return work[wpos++];
       }
   }
 }