From 60e9f0d726fd28b960c5674a3c7beaf7015dbd34 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 7 Jun 2003 18:35:00 +0000 Subject: [PATCH] re PR libgcj/8738 (java.io.CharArrayWriter's write methods erroneously throw IOExceptions) 2002-06-06 James Clark Fix for PR libgcj/8738: * gnu/gcj/convert/UnicodeToBytes.java (havePendingBytes): New method. * gnu/gcj/convert/Output_SJIS.java (havePendingBytes): Likewise. * gnu/gcj/convert/Output_EUCJIS.java (havePendingBytes): Likewise. * gnu/gcj/convert/Output_UTF8.java (havePendingBytes): Likewise. (write): Always decrease avail when count is increased. * java/lang/natString.cc (getBytes): Check converter havePendingBytes() and whether output buffer is full before increasing size. 2002-06-06 Mark Wielaard * java/io/PrintStream.java (writeChars(char[],int, int)): Check converter.havePendingBytes(). (writeChars(String,int,int)): Likewise. * java/io/OutputStreamWriter.java (writeChars(char[], int, int)): Check converter.havePendingBytes() and flush buffer when stalled. From-SVN: r67595 --- libjava/ChangeLog | 19 +++++++++++++++++++ libjava/gnu/gcj/convert/Output_EUCJIS.java | 7 ++++++- libjava/gnu/gcj/convert/Output_SJIS.java | 7 ++++++- libjava/gnu/gcj/convert/Output_UTF8.java | 9 ++++++++- libjava/gnu/gcj/convert/UnicodeToBytes.java | 13 ++++++++++++- libjava/java/io/OutputStreamWriter.java | 9 ++++++++- libjava/java/io/PrintStream.java | 6 +++--- libjava/java/lang/natString.cc | 12 ++++++------ 8 files changed, 68 insertions(+), 14 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index d29e51eb3c7..10e54f5f7de 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,22 @@ +2002-06-06 James Clark + + Fix for PR libgcj/8738: + * gnu/gcj/convert/UnicodeToBytes.java (havePendingBytes): New method. + * gnu/gcj/convert/Output_SJIS.java (havePendingBytes): Likewise. + * gnu/gcj/convert/Output_EUCJIS.java (havePendingBytes): Likewise. + * gnu/gcj/convert/Output_UTF8.java (havePendingBytes): Likewise. + (write): Always decrease avail when count is increased. + * java/lang/natString.cc (getBytes): Check converter havePendingBytes() + and whether output buffer is full before increasing size. + +2002-06-06 Mark Wielaard + + * java/io/PrintStream.java (writeChars(char[],int, int)): + Check converter.havePendingBytes(). + (writeChars(String,int,int)): Likewise. + * java/io/OutputStreamWriter.java (writeChars(char[], int, int)): + Check converter.havePendingBytes() and flush buffer when stalled. + 2003-06-07 Michael Koch * include/posix.h diff --git a/libjava/gnu/gcj/convert/Output_EUCJIS.java b/libjava/gnu/gcj/convert/Output_EUCJIS.java index 0662239aa85..c0cc4378b26 100644 --- a/libjava/gnu/gcj/convert/Output_EUCJIS.java +++ b/libjava/gnu/gcj/convert/Output_EUCJIS.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1999 Free Software Foundation +/* Copyright (C) 1999, 2003 Free Software Foundation This file is part of libgcj. @@ -22,6 +22,11 @@ public class Output_EUCJIS extends UnicodeToBytes public native int write (String str, int inpos, int inlength, char[] work); + public boolean havePendingBytes() + { + return pending1 >= 0; + } + int pending1 = -1; int pending2; } diff --git a/libjava/gnu/gcj/convert/Output_SJIS.java b/libjava/gnu/gcj/convert/Output_SJIS.java index c5370642378..67470ba7803 100644 --- a/libjava/gnu/gcj/convert/Output_SJIS.java +++ b/libjava/gnu/gcj/convert/Output_SJIS.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1999 Free Software Foundation +/* Copyright (C) 1999, 2003 Free Software Foundation This file is part of libgcj. @@ -22,5 +22,10 @@ public class Output_SJIS extends UnicodeToBytes public native int write (String str, int inpos, int inlength, char[] work); + public boolean havePendingBytes() + { + return pending >= 0; + } + int pending = -1; } diff --git a/libjava/gnu/gcj/convert/Output_UTF8.java b/libjava/gnu/gcj/convert/Output_UTF8.java index 01f5ce890e3..f54e7ebcfc2 100644 --- a/libjava/gnu/gcj/convert/Output_UTF8.java +++ b/libjava/gnu/gcj/convert/Output_UTF8.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* Copyright (C) 1999, 2000, 2003 Free Software Foundation This file is part of libgcj. @@ -104,6 +104,7 @@ public class Output_UTF8 extends UnicodeToBytes { value = (hi_part - 0xD800) * 0x400 + (ch - 0xDC00) + 0x10000; buf[count++] = (byte) (0xF0 | (value >> 18)); + avail--; bytes_todo = 3; hi_part = 0; } @@ -118,4 +119,10 @@ public class Output_UTF8 extends UnicodeToBytes } return inpos - start_pos; } + + public boolean havePendingBytes() + { + return bytes_todo > 0; + } + } diff --git a/libjava/gnu/gcj/convert/UnicodeToBytes.java b/libjava/gnu/gcj/convert/UnicodeToBytes.java index 8181cb83109..0785d7ea43e 100644 --- a/libjava/gnu/gcj/convert/UnicodeToBytes.java +++ b/libjava/gnu/gcj/convert/UnicodeToBytes.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2001 Free Software Foundation +/* Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation This file is part of libgcj. @@ -146,6 +146,17 @@ public abstract class UnicodeToBytes extends IOConverter return write(work, 0, srcEnd - inpos); } + /** + * Returns true when the converter has consumed some bytes that are + * not yet converted to characters because further continuation + * bytes are needed. Defaults to false, should be overridden by + * decoders that internally store some bytes. + */ + public boolean havePendingBytes() + { + return false; + } + /** Indicate that the converter is resuable. * This class keeps track of converters on a per-encoding basis. * When done with an encoder you may call this method to indicate diff --git a/libjava/java/io/OutputStreamWriter.java b/libjava/java/io/OutputStreamWriter.java index e4ecbdbab8f..8a47fdfc651 100644 --- a/libjava/java/io/OutputStreamWriter.java +++ b/libjava/java/io/OutputStreamWriter.java @@ -215,7 +215,7 @@ public class OutputStreamWriter extends Writer private void writeChars(char[] buf, int offset, int count) throws IOException { - while (count > 0) + while (count > 0 || converter.havePendingBytes()) { // We must flush if out.count == out.buf.length. // It is probably a good idea to flush if out.buf is almost full. @@ -228,6 +228,13 @@ public class OutputStreamWriter extends Writer } converter.setOutput(out.buf, out.count); int converted = converter.write(buf, offset, count); + // Flush if we cannot make progress. + if (converted == 0 && out.count == converter.count) + { + out.flush(); + if (out.count != 0) + throw new IOException("unable to flush output byte buffer"); + } offset += converted; count -= converted; out.count = converter.count; diff --git a/libjava/java/io/PrintStream.java b/libjava/java/io/PrintStream.java index ddc37aeb11e..489b3dd0dcd 100644 --- a/libjava/java/io/PrintStream.java +++ b/libjava/java/io/PrintStream.java @@ -1,5 +1,5 @@ /* PrintStream.java -- OutputStream for printing output - Copyright (C) 1998,2003 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -262,7 +262,7 @@ public class PrintStream extends FilterOutputStream private void writeChars(char[] buf, int offset, int count) throws IOException { - while (count > 0) + while (count > 0 || converter.havePendingBytes()) { converter.setOutput(work_bytes, 0); int converted = converter.write(buf, offset, count); @@ -275,7 +275,7 @@ public class PrintStream extends FilterOutputStream private void writeChars(String str, int offset, int count) throws IOException { - while (count > 0) + while (count > 0 || converter.havePendingBytes()) { converter.setOutput(work_bytes, 0); int converted = converter.write(str, offset, count, work); diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc index 8c9789e80b5..98309cfe62e 100644 --- a/libjava/java/lang/natString.cc +++ b/libjava/java/lang/natString.cc @@ -602,12 +602,12 @@ java::lang::String::getBytes (jstring enc) jint offset = 0; gnu::gcj::convert::UnicodeToBytes *converter = gnu::gcj::convert::UnicodeToBytes::getEncoder(enc); - while (todo > 0) + while (todo > 0 || converter->havePendingBytes()) { converter->setOutput(buffer, bufpos); int converted = converter->write(this, offset, todo, NULL); bufpos = converter->count; - if (converted == 0) + if (converted == 0 && bufpos == converter->count) { buflen *= 2; jbyteArray newbuffer = JvNewByteArray(buflen); @@ -615,10 +615,10 @@ java::lang::String::getBytes (jstring enc) buffer = newbuffer; } else - { - offset += converted; - todo -= converted; - } + bufpos = converter->count; + + offset += converted; + todo -= converted; } converter->done (); if (bufpos == buflen) -- 2.30.2