diff options
author | Tom Tromey <tromey@redhat.com> | 2001-07-13 05:41:28 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2001-07-13 05:41:28 +0000 |
commit | a9a399fe24303d933a412f01c01bb8e78d97cf9f (patch) | |
tree | 4aff078d910dc63cd6e5522da1dc415bc661bb0c /libjava/java/io/InputStreamReader.java | |
parent | c813baa415260f431f2a5c67312338802cbe5671 (diff) | |
download | gcc-a9a399fe24303d933a412f01c01bb8e78d97cf9f.zip gcc-a9a399fe24303d933a412f01c01bb8e78d97cf9f.tar.gz gcc-a9a399fe24303d933a412f01c01bb8e78d97cf9f.tar.bz2 |
re PR libgcj/3426 (java.io.InputStreamReader, infinite loop)
Fix for PR libgcj/3426:
* gnu/gcj/convert/natIconv.cc: Include CharConversionException.h,
errno.h.
(read): Throw exception if character conversion fails.
* java/io/BufferedInputStream.java (refill): Now package-private.
* java/io/InputStreamReader.java (ready): Simplified.
(refill): New method.
(read): Use it.
Co-Authored-By: David Brownell <david-b@pacbell.net>
From-SVN: r43975
Diffstat (limited to 'libjava/java/io/InputStreamReader.java')
-rw-r--r-- | libjava/java/io/InputStreamReader.java | 117 |
1 files changed, 57 insertions, 60 deletions
diff --git a/libjava/java/io/InputStreamReader.java b/libjava/java/io/InputStreamReader.java index 03a0c3e..45fd598 100644 --- a/libjava/java/io/InputStreamReader.java +++ b/libjava/java/io/InputStreamReader.java @@ -44,6 +44,11 @@ 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); @@ -76,28 +81,11 @@ public class InputStreamReader extends Reader 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; } } @@ -108,33 +96,23 @@ public class InputStreamReader extends Reader if (in == null) throw new IOException("Stream closed"); + if (length == 0) + return 0; + int wavail = wcount - wpos; - if (wavail > 0) - { - if (length > wavail) - length = wavail; - System.arraycopy(work, wpos, buf, offset, length); - wpos += length; - return length; - } - else + if (wavail <= 0) { - 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; } } @@ -146,24 +124,43 @@ public class InputStreamReader extends Reader 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++]; } } } |