diff --git a/components/net/sf/briar/transport/ConnectionWriterImpl.java b/components/net/sf/briar/transport/ConnectionWriterImpl.java index ee7ef1b41a3ce337055cda7ab6e98f6d4f5555e7..651034904c302fcbac281276223949b2fdc9ee10 100644 --- a/components/net/sf/briar/transport/ConnectionWriterImpl.java +++ b/components/net/sf/briar/transport/ConnectionWriterImpl.java @@ -13,6 +13,10 @@ import javax.crypto.Mac; import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.util.ByteUtils; +/** + * A ConnectionWriter that buffers its input and writes a frame whenever there + * is a full-size frame to write or the flush() method is called. + */ class ConnectionWriterImpl extends FilterOutputStream implements ConnectionWriter { @@ -45,8 +49,8 @@ implements ConnectionWriter { @Override public void write(int b) throws IOException { - if(buf.size() == maxPayloadLength) writeFrame(); buf.write(b); + if(buf.size() == maxPayloadLength) writeFrame(); } @Override @@ -57,7 +61,7 @@ implements ConnectionWriter { @Override public void write(byte[] b, int off, int len) throws IOException { int available = maxPayloadLength - buf.size(); - while(available < len) { + while(available <= len) { buf.write(b, off, available); writeFrame(); off += available; diff --git a/test/net/sf/briar/transport/ConnectionWriterImplTest.java b/test/net/sf/briar/transport/ConnectionWriterImplTest.java index 4640ab10f698e8298a19742720e93fe11233d2cf..bf11444b40d0a441f23a2d5694bf433f8e5cb1ac 100644 --- a/test/net/sf/briar/transport/ConnectionWriterImplTest.java +++ b/test/net/sf/briar/transport/ConnectionWriterImplTest.java @@ -45,21 +45,31 @@ public class ConnectionWriterImplTest extends TransportTest { } @Test - public void testFrameIsWrittenAtMaxLength() throws Exception { + public void testWriteByteToMaxLengthWritesFrame() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ConnectionEncrypter e = new NullConnectionEncrypter(out); ConnectionWriter w = new ConnectionWriterImpl(e, mac); OutputStream out1 = w.getOutputStream(); - // The first maxPayloadLength bytes should be buffered - for(int i = 0; i < maxPayloadLength; i++) out1.write(0); + // The first maxPayloadLength - 1 bytes should be buffered + for(int i = 0; i < maxPayloadLength - 1; i++) out1.write(0); assertEquals(0, out.size()); // The next byte should trigger the writing of a frame out1.write(0); assertEquals(MAX_FRAME_LENGTH, out.size()); - // Flushing the stream should write a single-byte frame - out1.flush(); - assertEquals(MAX_FRAME_LENGTH + headerLength + 1 + macLength, - out.size()); + } + + @Test + public void testWriteArrayToMaxLengthWritesFrame() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ConnectionEncrypter e = new NullConnectionEncrypter(out); + ConnectionWriter w = new ConnectionWriterImpl(e, mac); + OutputStream out1 = w.getOutputStream(); + // The first maxPayloadLength - 1 bytes should be buffered + out1.write(new byte[maxPayloadLength - 1]); + assertEquals(0, out.size()); + // The next maxPayloadLength + 1 bytes should trigger two frames + out1.write(new byte[maxPayloadLength + 1]); + assertEquals(MAX_FRAME_LENGTH * 2, out.size()); } @Test