* java/io/OutputStreamWriter.java (writeChars): Use a 'do' loop.
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Jun 2006 20:38:10 +0000 (20:38 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Jun 2006 20:38:10 +0000 (20:38 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115039 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/gnu/gcj/convert/CharsetToBytesAdaptor.java
libjava/gnu/gcj/convert/UnicodeToBytes.java
libjava/java/io/OutputStreamWriter.java
libjava/java/io/PrintStream.java
libjava/java/lang/natString.cc
libjava/testsuite/libjava.lang/RH194522.java [new file with mode: 0644]
libjava/testsuite/libjava.lang/RH194522.out [new file with mode: 0644]

index b6cbcf0..55c0762 100644 (file)
@@ -1,3 +1,22 @@
+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.
+
 2006-06-27  Marco Trudel  <mtrudel@gmx.ch>
 
        * boehm.cc (_Jv_SuspendThread, _Jv_ResumeThread): Define
index 4e9bcd5..80e749c 100644 (file)
@@ -39,6 +39,11 @@ public class CharsetToBytesAdaptor extends UnicodeToBytes
   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 @@ public class CharsetToBytesAdaptor extends UnicodeToBytes
     // 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,7 +141,12 @@ public class CharsetToBytesAdaptor extends UnicodeToBytes
    */
   public boolean havePendingBytes()
   {
-    return ! finished;
+    return hasBytes;
+  }
+
+  public void setFinished()
+  {
+    closedEncoder = true;
   }
 
   // These aren't cached.
index 8522bec..51d6939 100644 (file)
@@ -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 @@ public abstract class UnicodeToBytes extends IOConverter
     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 90ecd9f..1f1666f 100644 (file)
@@ -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 @@ public class OutputStreamWriter extends Writer
       {
        if (out != null)
          {
+           converter.setFinished();
            flush();
            out.close();
            out = null;
@@ -200,11 +201,11 @@ public class OutputStreamWriter extends Writer
        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 @@ public class OutputStreamWriter extends Writer
   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 @@ public class OutputStreamWriter extends Writer
          }
        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 @@ public class OutputStreamWriter extends Writer
          }
        offset += converted;
        count -= converted;
-       out.count = converter.count;
       }
+    while (count > 0 || converter.havePendingBytes());
   }
 
   /**
index 4756c8c..dc26eda 100644 (file)
@@ -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 @@ public class PrintStream extends FilterOutputStream
   {
     try
       {
+       converter.setFinished();
+       writeChars(new char[0], 0, 0);
        flush();
        out.close();
       }
@@ -251,7 +253,7 @@ public class PrintStream extends FilterOutputStream
   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 @@ public class PrintStream extends FilterOutputStream
        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 @@ public class PrintStream extends FilterOutputStream
        count -= converted;
        out.write(work_bytes, 0, converter.count);
       }
+    while (count > 0 || converter.havePendingBytes());
   }
 
   /**
index f3f3e4d..1a49bf7 100644 (file)
@@ -615,6 +615,8 @@ java::lang::String::getBytes (jstring enc)
   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)
diff --git a/libjava/testsuite/libjava.lang/RH194522.java b/libjava/testsuite/libjava.lang/RH194522.java
new file mode 100644 (file)
index 0000000..5ea446c
--- /dev/null
@@ -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();
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/RH194522.out b/libjava/testsuite/libjava.lang/RH194522.out
new file mode 100644 (file)
index 0000000..e69de29