changeset 1001:5fff68c9a9ec

Fixed TeeOutputStream to accept multi-byte encodings. Fixed TeeOutputStream to accept multi-byte encodings. * netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java: Now uses ByteArrayOutputStream instead of StringBuffer * tests/netx/unit/net/sourceforge/jnlp/util/logging/TeeOutputStreamTest.java:
author Jie Kang <jkang@redhat.com>
date Wed, 30 Jul 2014 14:17:43 -0400
parents 8e9179035018
children fe3feb87ede1
files ChangeLog netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java tests/netx/unit/net/sourceforge/jnlp/util/logging/TeeOutputStreamTest.java
diffstat 3 files changed, 109 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Jul 30 14:13:51 2014 -0400
+++ b/ChangeLog	Wed Jul 30 14:17:43 2014 -0400
@@ -1,3 +1,10 @@
+2014-07-30  Jie Kang  <jkang@redhat.com>
+	
+	Fixed TeeOutputStream to accept multi-byte encodings.
+	* netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java: Now uses
+	ByteArrayOutputStream instead of StringBuffer
+	* tests/netx/unit/net/sourceforge/jnlp/util/logging/TeeOutputStreamTest.java:
+
 2014-07-30  Jie Kang  <jkang@redhat.com>
 
 	Fix to Java ConsoleOutputPane for lower resolutions. Addresses bug
--- a/netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java	Wed Jul 30 14:13:51 2014 -0400
+++ b/netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java	Wed Jul 30 14:17:43 2014 -0400
@@ -38,14 +38,13 @@
 package net.sourceforge.jnlp.util.logging;
 
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.PrintStream;
-import net.sourceforge.jnlp.util.logging.JavaConsole;
-import net.sourceforge.jnlp.util.logging.OutputController;
+
 import net.sourceforge.jnlp.util.logging.OutputController.Level;
-import net.sourceforge.jnlp.util.logging.SingleStreamLogger;
 import net.sourceforge.jnlp.util.logging.headers.Header;
 import net.sourceforge.jnlp.util.logging.headers.JavaMessage;
-import net.sourceforge.jnlp.util.logging.headers.MessageWithHeader;
 
 /**
  * Behaves like the 'tee' command, sends output to both actual std stream and a
@@ -55,15 +54,15 @@
 
     // Everthing written to TeeOutputStream is written to our log too
     
-    private final StringBuffer string = new StringBuffer();
+    private final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
     private final boolean isError;
+    private final String lineSeparator = System.getProperty("line.separator");
 
     public TeeOutputStream(PrintStream stdStream, boolean isError) {
         super(stdStream);
         this.isError = isError;
     }
 
-
     @Override
     public void close() {
         flushLog();
@@ -82,32 +81,25 @@
 
     @Override
     public synchronized void write(byte[] b, int off, int len) {
-        if (b == null) {
-            throw new NullPointerException();
-        } else if ((off < 0) || (off > b.length) || (len < 0)
-                || ((off + len) > b.length) || ((off + len) < 0)) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
+        if (len == 0) {
             return;
         }
-        for (int i = 0; i < len; i++) {
-            appendChar(b[off + i]);
-        }
+        appendByteArray(b, off, len);
         super.write(b, off, len);
     }
 
     @Override
     public synchronized void write(int b) {
-        appendChar(b);
+        appendByte(b);
         super.write(b);
     }
 
     private void flushLog() {
-        if (string.length() <= 0 ){
-            return;
+        String s = byteArrayOutputStream.toString();
+        if (s.length() > 0) {
+            log(s);
+            byteArrayOutputStream.reset();
         }
-        log(string.toString());
-        string.setLength(0);
     }
 
     @Override
@@ -121,21 +113,34 @@
         return isError;
     }
 
-    private void appendChar(int b) {
-         if ( b <= 0 || b == '\n'){
+    private void appendByte(int b) {
+        byteArrayOutputStream.write(b);
+        String s = byteArrayOutputStream.toString();
+        if (s.endsWith(lineSeparator)) {
             flushLog();
-        } else {
-            string.append((char)b);
+        }
+    }
+
+    private void appendByteArray(byte[] b, int off, int len) {
+        byteArrayOutputStream.write(b, off, len);
+        String s = new String(b, off, len);
+        if (s.endsWith(lineSeparator)) {
+            flushLog();
         }
     }
 
     private Level getlevel() {
-        if (isError()){
+        if (isError()) {
             return OutputController.Level.ERROR_ALL;
         } else {
             return OutputController.Level.MESSAGE_ALL;
         }
     }
-    
-    
+
+    //For unit testing
+    protected ByteArrayOutputStream getByteArrayOutputStream() throws IOException {
+        ByteArrayOutputStream copy = new ByteArrayOutputStream();
+        copy.write(this.byteArrayOutputStream.toByteArray());
+        return copy;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/netx/unit/net/sourceforge/jnlp/util/logging/TeeOutputStreamTest.java	Wed Jul 30 14:17:43 2014 -0400
@@ -0,0 +1,70 @@
+package net.sourceforge.jnlp.util.logging;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by jkang on 15/07/14.
+ */
+public class TeeOutputStreamTest {
+
+    private PrintStream teePrintStream;
+    private TeeOutputStream tos;
+
+
+    @Before
+    public void setup() {
+        teePrintStream = new PrintStream(new ByteArrayOutputStream(), true);
+        tos = new TeeOutputStream(teePrintStream, false);
+    }
+    @Test
+    public void testPrintLn() throws IOException {
+        String s = "Hel你好lo \n World!";
+        tos.println(s); //println should be immediately flushed
+        assertTrue(tos.getByteArrayOutputStream().toString().isEmpty());
+    }
+
+    @Test
+    public void testPrint() throws IOException {
+        String s = "नमस्तHello!\r";
+        tos.print(s);
+        assertTrue(tos.getByteArrayOutputStream().toString().equals(s));
+    }
+
+    @Test
+    public void testWriteByteArrayString() throws IOException {
+        String s = "He\n\n\\llo chào";
+        tos.write(s.getBytes(), 0, s.getBytes().length);
+        assertTrue(tos.getByteArrayOutputStream().toString().equals(s.toString()));
+    }
+    @Test
+    public void testWriteByte() throws IOException {
+        byte b = 5;
+        tos.write(b);
+        assertTrue(byteArrayEquals(b, tos.getByteArrayOutputStream().toByteArray()));
+    }
+
+    @Test
+    public void testFlush() throws IOException {
+        String s = "Hello";
+        tos.print(s);
+        assertTrue(!tos.getByteArrayOutputStream().toString().isEmpty());
+        tos.flush();
+        assertTrue(tos.getByteArrayOutputStream().toString().isEmpty());
+    }
+
+    private boolean byteArrayEquals(byte b, byte[] arr) {
+        for (byte i : arr) {
+            if (b != i) {
+                return false;
+            }
+        }
+        return true;
+    }
+}