* Patch: FYI: fix OutputStreamWriter bug
@ 2006-06-27 20:35 Tom Tromey
0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2006-06-27 20:35 UTC (permalink / raw)
To: Java Patch List
I'm checking this in on the trunk.
This fixes a PR from the Red Hat bugzilla involving
OutputStreamWriter and java.nio charsets. A test case is included.
Tom
2006-06-27 Tom Tromey <tromey@redhat.com>
* java/io/OutputStreamWriter.java (writeChars): Use a 'do' loop.
Set 'out.count' earlier.
(close): Call setFinished on converter.
(flush): Always write work buffer.
* java/io/PrintStream.java (writeChars): Do 'do' loop.
(close): Call setFinished on converter. Write a 'flush' array.
* java/lang/natString.cc (getBytes): Call setFinished on
converter.
* gnu/gcj/convert/CharsetToBytesAdaptor.java (hasBytes): New
field.
(write): Set hasBytes. Changed 'finished' logic.
(havePendingBytes): Rewrote.
(setFinished): New method.
* gnu/gcj/convert/UnicodeToBytes.java (setFinished): New method.
* testsuite/libjava.lang/RH194522.java: New file.
* testsuite/libjava.lang/RH194522.out: New file.
Index: gnu/gcj/convert/UnicodeToBytes.java
===================================================================
--- gnu/gcj/convert/UnicodeToBytes.java (revision 115024)
+++ gnu/gcj/convert/UnicodeToBytes.java (working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation
This file is part of libgcj.
@@ -172,6 +172,15 @@
return false;
}
+ /**
+ * Users should call this method when the input is coming to an
+ * end. This signals that the next write (which might be
+ * zero-length) ought to flush any internal state.
+ */
+ public void setFinished()
+ {
+ }
+
/** 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
Index: gnu/gcj/convert/CharsetToBytesAdaptor.java
===================================================================
--- gnu/gcj/convert/CharsetToBytesAdaptor.java (revision 115024)
+++ gnu/gcj/convert/CharsetToBytesAdaptor.java (working copy)
@@ -39,6 +39,11 @@
private boolean closedEncoder;
/**
+ * True if there are bytes pending in the encoder.
+ */
+ private boolean hasBytes;
+
+ /**
* True if we're finished.
*/
private boolean finished;
@@ -112,20 +117,16 @@
// Set the current position.
outBuf.position(count);
- // If we've already said that there is no more input available,
- // then we simply try to flush again.
+ // Do the conversion.
+ CoderResult result = encoder.encode(inBuf, outBuf, closedEncoder);
+ hasBytes = result == CoderResult.OVERFLOW;
if (closedEncoder)
{
- CoderResult result = encoder.flush(outBuf);
+ result = encoder.flush(outBuf);
if (result == CoderResult.UNDERFLOW)
finished = true;
- }
- else
- {
- // Do the conversion. If there are no characters to write,
- // then we are finished.
- closedEncoder = ! inBuf.hasRemaining();
- encoder.encode(inBuf, outBuf, closedEncoder);
+ else
+ hasBytes = true;
}
// Mark the new end of buf.
@@ -140,9 +141,14 @@
*/
public boolean havePendingBytes()
{
- return ! finished;
+ return hasBytes;
}
+ public void setFinished()
+ {
+ closedEncoder = true;
+ }
+
// These aren't cached.
public void done()
{
Index: java/lang/natString.cc
===================================================================
--- java/lang/natString.cc (revision 115024)
+++ java/lang/natString.cc (working copy)
@@ -615,6 +615,8 @@
while (todo > 0 || converter->havePendingBytes())
{
converter->setOutput(buffer, bufpos);
+ // We only really need to do a single write.
+ converter->setFinished();
int converted = converter->write(this, offset, todo, NULL);
bufpos = converter->count;
if (converted == 0 && bufpos == converter->count)
Index: java/io/PrintStream.java
===================================================================
--- java/io/PrintStream.java (revision 115024)
+++ java/io/PrintStream.java (working copy)
@@ -1,5 +1,5 @@
/* PrintStream.java -- OutputStream for printing output
- Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -174,6 +174,8 @@
{
try
{
+ converter.setFinished();
+ writeChars(new char[0], 0, 0);
flush();
out.close();
}
@@ -251,7 +253,7 @@
private void writeChars(char[] buf, int offset, int count)
throws IOException
{
- while (count > 0 || converter.havePendingBytes())
+ do
{
converter.setOutput(work_bytes, 0);
int converted = converter.write(buf, offset, count);
@@ -259,12 +261,13 @@
count -= converted;
out.write(work_bytes, 0, converter.count);
}
+ while (count > 0 || converter.havePendingBytes());
}
private void writeChars(String str, int offset, int count)
throws IOException
{
- while (count > 0 || converter.havePendingBytes())
+ do
{
converter.setOutput(work_bytes, 0);
int converted = converter.write(str, offset, count, work);
@@ -272,6 +275,7 @@
count -= converted;
out.write(work_bytes, 0, converter.count);
}
+ while (count > 0 || converter.havePendingBytes());
}
/**
Index: java/io/OutputStreamWriter.java
===================================================================
--- java/io/OutputStreamWriter.java (revision 115024)
+++ java/io/OutputStreamWriter.java (working copy)
@@ -1,5 +1,5 @@
/* OutputStreamWriter.java -- Writer that converts chars to bytes
- Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -168,6 +168,7 @@
{
if (out != null)
{
+ converter.setFinished();
flush();
out.close();
out = null;
@@ -200,11 +201,11 @@
if (out == null)
throw new IOException("Stream closed");
- if (wcount > 0)
- {
- writeChars(work, 0, wcount);
- wcount = 0;
- }
+ // Always write -- if we are close()ing then we want to make
+ // sure the converter is flushed.
+ writeChars(work, 0, wcount);
+ wcount = 0;
+
out.flush();
}
}
@@ -243,7 +244,7 @@
private void writeChars(char[] buf, int offset, int count)
throws IOException
{
- while (count > 0 || converter.havePendingBytes())
+ do
{
// We must flush if out.count == out.buf.length.
// It is probably a good idea to flush if out.buf is almost full.
@@ -256,6 +257,9 @@
}
converter.setOutput(out.buf, out.count);
int converted = converter.write(buf, offset, count);
+ // Must set this before we flush the output stream, because
+ // flushing will reset 'out.count'.
+ out.count = converter.count;
// Flush if we cannot make progress.
if (converted == 0 && out.count == converter.count)
{
@@ -265,8 +269,8 @@
}
offset += converted;
count -= converted;
- out.count = converter.count;
}
+ while (count > 0 || converter.havePendingBytes());
}
/**
Index: testsuite/libjava.lang/RH194522.out
===================================================================
Index: testsuite/libjava.lang/RH194522.java
===================================================================
--- testsuite/libjava.lang/RH194522.java (revision 0)
+++ testsuite/libjava.lang/RH194522.java (revision 0)
@@ -0,0 +1,18 @@
+// Test case for http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=194522
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+public class RH194522
+{
+ public static void main(String[] args) throws Exception
+ {
+ Charset c = Charset.forName("UTF-8");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, c));
+ pw.println("hi");
+ pw.println("bob");
+ pw.flush();
+ pw.close();
+ }
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2006-06-27 20:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-27 20:35 Patch: FYI: fix OutputStreamWriter bug Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).