Bug 507664 - IOConsoleOutputStream does not handle multi-byte characters
at buffer boundaries correctly
Change-Id: Idfeabbcff7330541c5908ac4b3464a5cce1398ce
Signed-off-by: Andreas Loth <andy_2639@justmail.de>
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java
index 3939c4d..f53a2a3 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java
@@ -55,6 +55,9 @@
TestHelper.waitForJobs();
TestCase.assertEquals("whole test string should be written", testString, document.get()); //$NON-NLS-1$
}
+ // after closing the stream, the document content should still be the
+ // same
+ TestCase.assertEquals("closing the stream should not alter the document", testString, document.get()); //$NON-NLS-1$
}
}
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsoleOutputStream.java b/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsoleOutputStream.java
index 7e78ddf..70291df 100644
--- a/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsoleOutputStream.java
+++ b/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsoleOutputStream.java
@@ -14,6 +14,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.internal.console.IOConsolePartitioner;
@@ -158,6 +159,20 @@
return closed;
}
+ /**
+ * Writes remaining characters stored in the decoder state.
+ *
+ * Must only be called from synchronized methods.
+ *
+ * @see CharsetDecoder#flush(java.nio.CharBuffer)
+ * @throws IOException
+ */
+ private void finishDecoder() throws IOException {
+ StringBuilder builder = new StringBuilder();
+ this.decoder.finish(builder);
+ this.encodedWrite(builder.toString());
+ }
+
/*
* (non-Javadoc)
* @see java.io.OutputStream#close()
@@ -168,6 +183,7 @@
// Closeable#close() has no effect if already closed
return;
}
+ this.finishDecoder();
if (prependCR) { // force writing of last /r
prependCR = false;
notifyParitioner("\r"); //$NON-NLS-1$
@@ -193,7 +209,7 @@
* @see java.io.OutputStream#write(byte[], int, int)
*/
@Override
- public void write(byte[] b, int off, int len) throws IOException {
+ public synchronized void write(byte[] b, int off, int len) throws IOException {
StringBuilder builder = new StringBuilder();
this.decoder.decode(builder, b, off, len);
encodedWrite(builder.toString());
@@ -317,10 +333,8 @@
* @throws IOException if the stream is closed
* @since 3.7
*/
- public void setCharset(Charset charset) throws IOException {
- StringBuilder builder = new StringBuilder();
- this.decoder.finish(builder);
- this.encodedWrite(builder.toString());
+ public synchronized void setCharset(Charset charset) throws IOException {
+ this.finishDecoder();
this.decoder = new StreamDecoder(charset);
}