From 7e58b256186dc6cdb5ff688f4acfa20ba3f2b80b Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Wed, 21 Sep 2011 13:47:06 +0100
Subject: [PATCH] Allow the max packet length to be reduced from the default.

---
 .../briar/api/protocol/writers/AckWriter.java |  6 ++
 .../api/protocol/writers/BatchWriter.java     |  6 ++
 .../api/protocol/writers/OfferWriter.java     |  6 ++
 .../briar/protocol/writers/AckWriterImpl.java | 11 ++-
 .../protocol/writers/BatchWriterImpl.java     | 11 ++-
 .../protocol/writers/OfferWriterImpl.java     | 11 ++-
 .../briar/protocol/writers/ConstantsTest.java | 74 ++++++++++++++++---
 7 files changed, 108 insertions(+), 17 deletions(-)

diff --git a/api/net/sf/briar/api/protocol/writers/AckWriter.java b/api/net/sf/briar/api/protocol/writers/AckWriter.java
index 237a487ab9..80fbd88681 100644
--- a/api/net/sf/briar/api/protocol/writers/AckWriter.java
+++ b/api/net/sf/briar/api/protocol/writers/AckWriter.java
@@ -7,6 +7,12 @@ import net.sf.briar.api.protocol.BatchId;
 /** An interface for creating an ack packet. */
 public interface AckWriter {
 
+	/**
+	 * Sets the maximum length of the serialised ack. If this method is not
+	 * called, the default is ProtocolConstants.MAX_PACKET_LENGTH;
+	 */
+	void setMaxPacketLength(int length);
+
 	/**
 	 * Attempts to add the given BatchId to the ack and returns true if it
 	 * was added.
diff --git a/api/net/sf/briar/api/protocol/writers/BatchWriter.java b/api/net/sf/briar/api/protocol/writers/BatchWriter.java
index 60818ac569..e14aa127e7 100644
--- a/api/net/sf/briar/api/protocol/writers/BatchWriter.java
+++ b/api/net/sf/briar/api/protocol/writers/BatchWriter.java
@@ -7,6 +7,12 @@ import net.sf.briar.api.protocol.BatchId;
 /** An interface for creating a batch packet. */
 public interface BatchWriter {
 
+	/**
+	 * Sets the maximum length of the serialised batch. If this method is not
+	 * called, the default is ProtocolConstants.MAX_PACKET_LENGTH;
+	 */
+	void setMaxPacketLength(int length);
+
 	/**
 	 * Attempts to add the given raw message to the batch and returns true if
 	 * it was added.
diff --git a/api/net/sf/briar/api/protocol/writers/OfferWriter.java b/api/net/sf/briar/api/protocol/writers/OfferWriter.java
index 8faee5bed2..35bdafe926 100644
--- a/api/net/sf/briar/api/protocol/writers/OfferWriter.java
+++ b/api/net/sf/briar/api/protocol/writers/OfferWriter.java
@@ -7,6 +7,12 @@ import net.sf.briar.api.protocol.MessageId;
 /** An interface for creating an offer packet. */
 public interface OfferWriter {
 
+	/**
+	 * Sets the maximum length of the serialised offer. If this method is not
+	 * called, the default is ProtocolConstants.MAX_PACKET_LENGTH;
+	 */
+	void setMaxPacketLength(int length);
+
 	/**
 	 * Attempts to add the given message ID to the offer and returns true if it
 	 * was added.
diff --git a/components/net/sf/briar/protocol/writers/AckWriterImpl.java b/components/net/sf/briar/protocol/writers/AckWriterImpl.java
index 2da1a1cece..f1d9722cb4 100644
--- a/components/net/sf/briar/protocol/writers/AckWriterImpl.java
+++ b/components/net/sf/briar/protocol/writers/AckWriterImpl.java
@@ -18,7 +18,7 @@ class AckWriterImpl implements AckWriter {
 	private final Writer w;
 
 	private boolean started = false;
-	private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
+	private int capacity = ProtocolConstants.MAX_PACKET_LENGTH;
 
 	AckWriterImpl(OutputStream out, SerialComponent serial,
 			WriterFactory writerFactory) {
@@ -30,6 +30,13 @@ class AckWriterImpl implements AckWriter {
 		w = writerFactory.createWriter(out);
 	}
 
+	public void setMaxPacketLength(int length) {
+		if(started) throw new IllegalStateException();
+		if(length < 0 || length > ProtocolConstants.MAX_PACKET_LENGTH)
+			throw new IllegalArgumentException();
+		capacity = length;
+	}
+
 	public boolean writeBatchId(BatchId b) throws IOException {
 		int overhead = started ? footerLength : headerLength + footerLength;
 		if(capacity < idLength + overhead) return false;
@@ -43,7 +50,7 @@ class AckWriterImpl implements AckWriter {
 		if(!started) start();
 		w.writeListEnd();
 		out.flush();
-		capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
+		capacity = ProtocolConstants.MAX_PACKET_LENGTH;
 		started = false;
 	}
 
diff --git a/components/net/sf/briar/protocol/writers/BatchWriterImpl.java b/components/net/sf/briar/protocol/writers/BatchWriterImpl.java
index 96c982e6a8..bc6bfb0f8e 100644
--- a/components/net/sf/briar/protocol/writers/BatchWriterImpl.java
+++ b/components/net/sf/briar/protocol/writers/BatchWriterImpl.java
@@ -21,7 +21,7 @@ class BatchWriterImpl implements BatchWriter {
 	private final MessageDigest messageDigest;
 
 	private boolean started = false;
-	private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
+	private int capacity = ProtocolConstants.MAX_PACKET_LENGTH;
 
 	BatchWriterImpl(OutputStream out, SerialComponent serial,
 			WriterFactory writerFactory, MessageDigest messageDigest) {
@@ -33,6 +33,13 @@ class BatchWriterImpl implements BatchWriter {
 		this.messageDigest = messageDigest;
 	}
 
+	public void setMaxPacketLength(int length) {
+		if(started) throw new IllegalStateException();
+		if(length < 0 || length > ProtocolConstants.MAX_PACKET_LENGTH)
+			throw new IllegalArgumentException();
+		capacity = length;
+	}
+
 	public boolean writeMessage(byte[] message) throws IOException {
 		int overhead = started ? footerLength : headerLength + footerLength;
 		if(capacity < message.length + overhead) return false;
@@ -47,7 +54,7 @@ class BatchWriterImpl implements BatchWriter {
 		if(!started) start();
 		w.writeListEnd();
 		out.flush();
-		capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
+		capacity = ProtocolConstants.MAX_PACKET_LENGTH;
 		started = false;
 		return new BatchId(messageDigest.digest());
 	}
diff --git a/components/net/sf/briar/protocol/writers/OfferWriterImpl.java b/components/net/sf/briar/protocol/writers/OfferWriterImpl.java
index 40a9221afa..04303fbf4d 100644
--- a/components/net/sf/briar/protocol/writers/OfferWriterImpl.java
+++ b/components/net/sf/briar/protocol/writers/OfferWriterImpl.java
@@ -18,7 +18,7 @@ class OfferWriterImpl implements OfferWriter {
 	private final Writer w;
 
 	private boolean started = false;
-	private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
+	private int capacity = ProtocolConstants.MAX_PACKET_LENGTH;
 
 	OfferWriterImpl(OutputStream out, SerialComponent serial,
 			WriterFactory writerFactory) {
@@ -30,6 +30,13 @@ class OfferWriterImpl implements OfferWriter {
 		w = writerFactory.createWriter(out);
 	}
 
+	public void setMaxPacketLength(int length) {
+		if(started) throw new IllegalStateException();
+		if(length < 0 || length > ProtocolConstants.MAX_PACKET_LENGTH)
+			throw new IllegalArgumentException();
+		capacity = length;
+	}
+
 	public boolean writeMessageId(MessageId m) throws IOException {
 		int overhead = started ? footerLength : headerLength + footerLength;
 		if(capacity < idLength + overhead) return false;
@@ -43,7 +50,7 @@ class OfferWriterImpl implements OfferWriter {
 		if(!started) start();
 		w.writeListEnd();
 		out.flush();
-		capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
+		capacity = ProtocolConstants.MAX_PACKET_LENGTH;
 		started = false;
 	}
 
diff --git a/test/net/sf/briar/protocol/writers/ConstantsTest.java b/test/net/sf/briar/protocol/writers/ConstantsTest.java
index 6115e08af7..d6a50b20db 100644
--- a/test/net/sf/briar/protocol/writers/ConstantsTest.java
+++ b/test/net/sf/briar/protocol/writers/ConstantsTest.java
@@ -58,15 +58,35 @@ public class ConstantsTest extends TestCase {
 	}
 
 	@Test
-	public void testBatchesFitIntoAck() throws Exception {
-		// Create an ack with the maximum number of batch IDs
-		ByteArrayOutputStream out = new ByteArrayOutputStream(
-				ProtocolConstants.MAX_PACKET_LENGTH);
+	public void testBatchesFitIntoLargeAck() throws Exception {
+		testBatchesFitIntoAck(ProtocolConstants.MAX_PACKET_LENGTH);
+	}
+
+	@Test
+	public void testBatchesFitIntoSmallAck() throws Exception {
+		testBatchesFitIntoAck(1000);
+	}
+
+	private void testBatchesFitIntoAck(int length) throws Exception {
+		// Create an ack with as many batch IDs as possible
+		ByteArrayOutputStream out = new ByteArrayOutputStream(length);
 		AckWriter a = new AckWriterImpl(out, serial, writerFactory);
+		a.setMaxPacketLength(length);
 		while(a.writeBatchId(new BatchId(TestUtils.getRandomId())));
 		a.finish();
 		// Check the size of the serialised ack
-		assertTrue(out.size() <= ProtocolConstants.MAX_PACKET_LENGTH);
+		assertTrue(out.size() <= length);
+	}
+
+	@Test
+	public void testEmptyAck() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		AckWriter a = new AckWriterImpl(out, serial, writerFactory);
+		// There's not enough room for a batch ID
+		a.setMaxPacketLength(4);
+		assertFalse(a.writeBatchId(new BatchId(TestUtils.getRandomId())));
+		// Check that nothing was written
+		assertEquals(0, out.size());
 	}
 
 	@Test
@@ -90,7 +110,7 @@ public class ConstantsTest extends TestCase {
 				ProtocolConstants.MAX_PACKET_LENGTH);
 		BatchWriter b = new BatchWriterImpl(out, serial, writerFactory,
 				crypto.getMessageDigest());
-		b.writeMessage(message.getBytes());
+		assertTrue(b.writeMessage(message.getBytes()));
 		b.finish();
 		// Check the size of the serialised batch
 		assertTrue(out.size() > UniqueId.LENGTH + Group.MAX_NAME_LENGTH +
@@ -100,15 +120,47 @@ public class ConstantsTest extends TestCase {
 	}
 
 	@Test
-	public void testMessagesFitIntoOffer() throws Exception {
-		// Create an offer with the maximum number of message IDs
-		ByteArrayOutputStream out = new ByteArrayOutputStream(
-				ProtocolConstants.MAX_PACKET_LENGTH);
+	public void testEmptyBatch() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		BatchWriter b = new BatchWriterImpl(out, serial, writerFactory,
+				crypto.getMessageDigest());
+		// There's not enough room for a message
+		b.setMaxPacketLength(4);
+		assertFalse(b.writeMessage(new byte[4]));
+		// Check that nothing was written
+		assertEquals(0, out.size());
+	}
+
+	@Test
+	public void testMessagesFitIntoLargeOffer() throws Exception {
+		testMessagesFitIntoOffer(ProtocolConstants.MAX_PACKET_LENGTH);
+	}
+
+	@Test
+	public void testMessagesFitIntoSmallOffer() throws Exception {
+		testMessagesFitIntoOffer(1000);
+	}
+
+	private void testMessagesFitIntoOffer(int length) throws Exception {
+		// Create an offer with as many message IDs as possible
+		ByteArrayOutputStream out = new ByteArrayOutputStream(length);
 		OfferWriter o = new OfferWriterImpl(out, serial, writerFactory);
+		o.setMaxPacketLength(length);
 		while(o.writeMessageId(new MessageId(TestUtils.getRandomId())));
 		o.finish();
 		// Check the size of the serialised offer
-		assertTrue(out.size() <= ProtocolConstants.MAX_PACKET_LENGTH);
+		assertTrue(out.size() <= length);
+	}
+
+	@Test
+	public void testEmptyOffer() throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		OfferWriter o = new OfferWriterImpl(out, serial, writerFactory);
+		// There's not enough room for a message ID
+		o.setMaxPacketLength(4);
+		assertFalse(o.writeMessageId(new MessageId(TestUtils.getRandomId())));
+		// Check that nothing was written
+		assertEquals(0, out.size());
 	}
 
 	@Test
-- 
GitLab