|
From: <cr...@us...> - 2008-09-04 14:09:44
|
Revision: 4540
http://jnode.svn.sourceforge.net/jnode/?rev=4540&view=rev
Author: crawley
Date: 2008-09-04 14:09:40 +0000 (Thu, 04 Sep 2008)
Log Message:
-----------
Bug fixes for WriterOutputStream + unit tests
Modified Paths:
--------------
trunk/shell/src/shell/org/jnode/shell/io/WriterOutputStream.java
Added Paths:
-----------
trunk/shell/src/test/org/jnode/test/shell/io/WriterOutputStreamTest.java
Modified: trunk/shell/src/shell/org/jnode/shell/io/WriterOutputStream.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/io/WriterOutputStream.java 2008-09-03 23:43:55 UTC (rev 4539)
+++ trunk/shell/src/shell/org/jnode/shell/io/WriterOutputStream.java 2008-09-04 14:09:40 UTC (rev 4540)
@@ -7,12 +7,13 @@
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
public class WriterOutputStream extends OutputStream {
// TODO deal with decoder errors.
private ByteBuffer bytes = ByteBuffer.allocate(2048);
- private CharBuffer chars = CharBuffer.allocate(1024);
+ private CharBuffer chars = CharBuffer.allocate(2048);
private Writer writer;
private CharsetDecoder decoder;
@@ -20,24 +21,53 @@
public WriterOutputStream(Writer writer, String encoding) {
this.writer = writer;
this.decoder = Charset.forName(encoding).newDecoder();
+ bytes.clear();
+ chars.clear();
}
@Override
public void write(int b) throws IOException {
bytes.put((byte) b);
if (bytes.remaining() == 0) {
- decoder.decode(bytes, chars, false);
- flush();
+ flush(false);
}
}
@Override
public void flush() throws IOException {
- if (chars.position() > 0) {
- int len = chars.position();
- int pos = chars.arrayOffset();
- writer.write(chars.array(), pos, len);
+ flush(false);
+ }
+
+ @Override
+ public void close() throws IOException {
+ flush(true);
+ writer.close();
+ }
+
+ private int flush(boolean all) throws IOException {
+ if (bytes.position() > 0) {
+ bytes.flip();
chars.clear();
+ CoderResult cr = decoder.decode(bytes, chars, all);
+ int count = chars.position();
+ if (count > 0) {
+ int pos = chars.arrayOffset();
+ writer.write(chars.array(), pos, count);
+ }
+ if (cr.isError() || (all && cr == CoderResult.UNDERFLOW)) {
+ cr.throwException();
+ }
+ if (bytes.remaining() > 0) {
+ byte[] tmp = new byte[bytes.remaining()];
+ bytes.get(tmp);
+ bytes.clear();
+ bytes.put(tmp);
+ } else {
+ bytes.clear();
+ }
+ return count;
+ } else {
+ return 0;
}
}
@@ -47,13 +77,13 @@
throw new IndexOutOfBoundsException();
}
while (len > 0) {
- int pos = bytes.position();
- bytes.put(b, off, len);
- int count = bytes.position() - pos;
- off += count;
- len -= count;
- decoder.decode(bytes, chars, false);
- flush();
+ int toWrite = Math.min(len, bytes.remaining());
+ bytes.put(b, off, toWrite);
+ off += toWrite;
+ len -= toWrite;
+ if (bytes.remaining() == 0) {
+ flush(false);
+ }
}
}
Added: trunk/shell/src/test/org/jnode/test/shell/io/WriterOutputStreamTest.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/io/WriterOutputStreamTest.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/io/WriterOutputStreamTest.java 2008-09-04 14:09:40 UTC (rev 4540)
@@ -0,0 +1,153 @@
+/*
+ * $Id: ThreadCommandInvoker.java 3374 2007-08-02 18:15:27Z lsantha $
+ *
+ * JNode.org
+ * Copyright (C) 2007 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jnode.test.shell.io;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+
+import junit.framework.TestCase;
+
+import org.jnode.shell.io.ReaderInputStream;
+import org.jnode.shell.io.WriterOutputStream;
+
+public class WriterOutputStreamTest extends TestCase {
+
+ public void testEmpty() throws Exception {
+ String LINE = "";
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ byte[] buffer = LINE.getBytes();
+ wos.write(buffer);
+ wos.flush();
+ assertEquals(LINE, sw.getBuffer().toString());
+ }
+
+ public void testLine() throws Exception {
+ String LINE = "The quick brown fox jumped over the lazy doc";
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ byte[] buffer = LINE.getBytes();
+ wos.write(buffer);
+ wos.flush();
+ assertEquals(LINE, sw.getBuffer().toString());
+ }
+
+ public void testByteAtATime() throws Exception {
+ String LINE = "The quick brown fox jumped over the lazy doc";
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ byte[] buffer = LINE.getBytes();
+ for (byte b : buffer) {
+ wos.write(b);
+ }
+ wos.flush();
+ assertEquals(LINE, sw.getBuffer().toString());
+ }
+
+ public void testByteAtATimeWithFlushes() throws Exception {
+ String LINE = "The quick brown fox jumped over the lazy doc";
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ byte[] buffer = LINE.getBytes();
+ for (int i = 0; i < buffer.length; i++) {
+ wos.write(buffer[i]);
+ wos.flush();
+ assertEquals(LINE.charAt(i), sw.getBuffer().charAt(i));
+ }
+ assertEquals(LINE, sw.getBuffer().toString());
+ }
+
+ public void testUnicode() throws Exception {
+ char[] chars = new char[8192];
+ for (int i = 0; i < chars.length; i++) {
+ chars[i] = (char) i;
+ }
+ byte[] buffer = new String(chars).getBytes();
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ wos.write(buffer);
+ wos.flush();
+ StringBuffer sb = sw.getBuffer();
+ assertEquals(chars.length, sb.length());
+ for (int i = 0; i < chars.length; i++) {
+ assertEquals(chars[i], sb.charAt(i));
+ }
+ }
+
+ public void testBadUnicode() throws Exception {
+ byte[] BAD = new byte[] {(byte) 0x80};
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ try {
+ wos.write(BAD);
+ wos.flush();
+ fail("no exception thrown");
+ } catch (MalformedInputException ex) {
+ // expected
+ }
+ }
+
+ public void testBadUnicode2() throws Exception {
+ byte[] BAD = new byte[] {(byte) 'h', (byte) 'i', (byte) 0x80};
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ try {
+ wos.write(BAD);
+ wos.flush();
+ fail("no exception thrown");
+ } catch (MalformedInputException ex) {
+ // expected
+ assertEquals("hi", sw.getBuffer().toString());
+ }
+ }
+
+ public void testBadUnicode3() throws Exception {
+ byte[] BAD = new byte[] {(byte) 'h', (byte) 'i', (byte) 0xc2, (byte) 0x00};
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ try {
+ wos.write(BAD);
+ wos.flush();
+ fail("no exception thrown");
+ } catch (MalformedInputException ex) {
+ // expected
+ assertEquals("hi", sw.getBuffer().toString());
+ }
+ }
+
+ public void testBadUnicode4() throws Exception {
+ byte[] BAD = new byte[] {(byte) 'h', (byte) 'i', (byte) 0xc2};
+ StringWriter sw = new StringWriter();
+ WriterOutputStream wos = new WriterOutputStream(sw, "UTF-8");
+ wos.write(BAD);
+ wos.flush();
+ try {
+ wos.close();
+ fail("no exception thrown");
+ } catch (MalformedInputException ex) {
+ // expected
+ assertEquals("hi", sw.getBuffer().toString());
+ }
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|