diff --git a/briar-tests/build.xml b/briar-tests/build.xml
index 5211bfe17..8bbb88e7d 100644
--- a/briar-tests/build.xml
+++ b/briar-tests/build.xml
@@ -88,12 +88,10 @@
-
-
+
-
diff --git a/briar-tests/src/net/sf/briar/ProtocolIntegrationTest.java b/briar-tests/src/net/sf/briar/ProtocolIntegrationTest.java
index abca57ba3..5abda455f 100644
--- a/briar-tests/src/net/sf/briar/ProtocolIntegrationTest.java
+++ b/briar-tests/src/net/sf/briar/ProtocolIntegrationTest.java
@@ -15,6 +15,7 @@ import java.util.Collections;
import java.util.Random;
import net.sf.briar.api.ContactId;
+import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.Author;
@@ -64,7 +65,6 @@ public class ProtocolIntegrationTest extends BriarTestCase {
private final MessageVerifier messageVerifier;
private final ContactId contactId;
- private final TransportId transportId;
private final byte[] secret;
private final Author author;
private final Group group, group1;
@@ -73,7 +73,8 @@ public class ProtocolIntegrationTest extends BriarTestCase {
private final String subject = "Hello";
private final String messageBody = "Hello world";
private final Collection messageIds;
- private final Collection transports;
+ private final TransportId transportId;
+ private final TransportProperties transportProperties;
public ProtocolIntegrationTest() throws Exception {
super();
@@ -88,7 +89,6 @@ public class ProtocolIntegrationTest extends BriarTestCase {
protocolWriterFactory = i.getInstance(ProtocolWriterFactory.class);
messageVerifier = i.getInstance(MessageVerifier.class);
contactId = new ContactId(234);
- transportId = new TransportId(TestUtils.getRandomId());
// Create a shared secret
secret = new byte[32];
new Random().nextBytes(secret);
@@ -119,11 +119,10 @@ public class ProtocolIntegrationTest extends BriarTestCase {
subject, messageBody.getBytes("UTF-8"));
messageIds = Arrays.asList(message.getId(),
message1.getId(), message2.getId(), message3.getId());
- // Create some transports
- TransportId transportId = new TransportId(TestUtils.getRandomId());
- Transport transport = new Transport(transportId,
- Collections.singletonMap("bar", "baz"));
- transports = Collections.singletonList(transport);
+ // Create some transport properties
+ transportId = new TransportId(TestUtils.getRandomId());
+ transportProperties = new TransportProperties(Collections.singletonMap(
+ "bar", "baz"));
}
@Test
@@ -155,16 +154,13 @@ public class ProtocolIntegrationTest extends BriarTestCase {
requested.set(3);
writer.writeRequest(new Request(requested, 4));
- Collection holes = Arrays.asList(
- new SubscriptionHole(group.getId(), group1.getId()));
- Collection subs = Arrays.asList(
- new Subscription(group, 0L), new Subscription(group1, 0L));
- SubscriptionUpdate s = new SubscriptionUpdate(holes, subs, 0L,
- subscriptionVersion);
- writer.writeSubscriptionUpdate(s);
+ SubscriptionUpdate su = new SubscriptionUpdate(
+ Arrays.asList(group, group1), 1L);
+ writer.writeSubscriptionUpdate(su);
- TransportUpdate t = new TransportUpdate(transports, transportVersion);
- writer.writeTransportUpdate(t);
+ TransportUpdate tu = new TransportUpdate(transportId,
+ transportProperties, 1L);
+ writer.writeTransportUpdate(tu);
writer.flush();
return out.toByteArray();
@@ -219,13 +215,16 @@ public class ProtocolIntegrationTest extends BriarTestCase {
// Read the subscription update
assertTrue(reader.hasSubscriptionUpdate());
- SubscriptionUpdate s = reader.readSubscriptionUpdate();
- // FIXME: Test for equality
+ SubscriptionUpdate su = reader.readSubscriptionUpdate();
+ assertEquals(Arrays.asList(group, group1), su.getGroups());
+ assertEquals(1L, su.getVersion());
// Read the transport update
assertTrue(reader.hasTransportUpdate());
- TransportUpdate t = reader.readTransportUpdate();
- // FIXME: Test for equality
+ TransportUpdate tu = reader.readTransportUpdate();
+ assertEquals(transportId, tu.getId());
+ assertEquals(transportProperties, tu.getProperties());
+ assertEquals(1L, tu.getVersion());
in.close();
}
diff --git a/briar-tests/src/net/sf/briar/protocol/AckReaderTest.java b/briar-tests/src/net/sf/briar/protocol/AckReaderTest.java
deleted file mode 100644
index 82f792ab2..000000000
--- a/briar-tests/src/net/sf/briar/protocol/AckReaderTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package net.sf.briar.protocol;
-
-import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
-import static net.sf.briar.api.protocol.Types.ACK;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-import net.sf.briar.BriarTestCase;
-import net.sf.briar.TestUtils;
-import net.sf.briar.api.FormatException;
-import net.sf.briar.api.protocol.Ack;
-import net.sf.briar.api.serial.Reader;
-import net.sf.briar.api.serial.ReaderFactory;
-import net.sf.briar.api.serial.SerialComponent;
-import net.sf.briar.api.serial.Writer;
-import net.sf.briar.api.serial.WriterFactory;
-import net.sf.briar.serial.SerialModule;
-
-import org.junit.Test;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-public class AckReaderTest extends BriarTestCase {
-
- // FIXME: This is an integration test, not a unit test
-
- private final SerialComponent serial;
- private final ReaderFactory readerFactory;
- private final WriterFactory writerFactory;
-
- public AckReaderTest() throws Exception {
- super();
- Injector i = Guice.createInjector(new SerialModule());
- serial = i.getInstance(SerialComponent.class);
- readerFactory = i.getInstance(ReaderFactory.class);
- writerFactory = i.getInstance(WriterFactory.class);
- }
-
- @Test
- public void testFormatExceptionIfAckIsTooLarge() throws Exception {
- byte[] b = createAck(true);
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(ACK, new AckReader());
- try {
- reader.readStruct(ACK, Ack.class);
- fail();
- } catch(FormatException expected) {}
- }
-
- @Test
- public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
- byte[] b = createAck(false);
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(ACK, new AckReader());
- reader.readStruct(ACK, Ack.class);
- }
-
- @Test
- public void testEmptyAck() throws Exception {
- byte[] b = createEmptyAck();
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(ACK, new AckReader());
- try {
- reader.readStruct(ACK, Ack.class);
- fail();
- } catch(FormatException expected) {}
- }
-
- private byte[] createAck(boolean tooBig) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Writer w = writerFactory.createWriter(out);
- w.writeStructId(ACK);
- w.writeListStart();
- while(out.size() + serial.getSerialisedUniqueIdLength()
- < MAX_PACKET_LENGTH) {
- w.writeBytes(TestUtils.getRandomId());
- }
- if(tooBig) w.writeBytes(TestUtils.getRandomId());
- w.writeListEnd();
- assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
- return out.toByteArray();
- }
-
- private byte[] createEmptyAck() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Writer w = writerFactory.createWriter(out);
- w.writeStructId(ACK);
- w.writeListStart();
- w.writeListEnd();
- return out.toByteArray();
- }
-}
diff --git a/briar-tests/src/net/sf/briar/protocol/OfferReaderTest.java b/briar-tests/src/net/sf/briar/protocol/OfferReaderTest.java
deleted file mode 100644
index e10da58b0..000000000
--- a/briar-tests/src/net/sf/briar/protocol/OfferReaderTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package net.sf.briar.protocol;
-
-import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
-import static net.sf.briar.api.protocol.Types.OFFER;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-import net.sf.briar.BriarTestCase;
-import net.sf.briar.TestUtils;
-import net.sf.briar.api.FormatException;
-import net.sf.briar.api.protocol.Offer;
-import net.sf.briar.api.serial.Reader;
-import net.sf.briar.api.serial.ReaderFactory;
-import net.sf.briar.api.serial.SerialComponent;
-import net.sf.briar.api.serial.Writer;
-import net.sf.briar.api.serial.WriterFactory;
-import net.sf.briar.serial.SerialModule;
-
-import org.junit.Test;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-public class OfferReaderTest extends BriarTestCase {
-
- // FIXME: This is an integration test, not a unit test
-
- private final SerialComponent serial;
- private final ReaderFactory readerFactory;
- private final WriterFactory writerFactory;
-
- public OfferReaderTest() throws Exception {
- super();
- Injector i = Guice.createInjector(new SerialModule());
- serial = i.getInstance(SerialComponent.class);
- readerFactory = i.getInstance(ReaderFactory.class);
- writerFactory = i.getInstance(WriterFactory.class);
- }
-
- @Test
- public void testFormatExceptionIfOfferIsTooLarge() throws Exception {
- byte[] b = createOffer(true);
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(OFFER, new OfferReader());
- try {
- reader.readStruct(OFFER, Offer.class);
- fail();
- } catch(FormatException expected) {}
- }
-
- @Test
- public void testNoFormatExceptionIfOfferIsMaximumSize() throws Exception {
- byte[] b = createOffer(false);
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(OFFER, new OfferReader());
- reader.readStruct(OFFER, Offer.class);
- }
-
- @Test
- public void testEmptyOffer() throws Exception {
- byte[] b = createEmptyOffer();
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(OFFER, new OfferReader());
- try {
- reader.readStruct(OFFER, Offer.class);
- fail();
- } catch(FormatException expected) {}
- }
-
- private byte[] createOffer(boolean tooBig) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Writer w = writerFactory.createWriter(out);
- w.writeStructId(OFFER);
- w.writeListStart();
- while(out.size() + serial.getSerialisedUniqueIdLength()
- < MAX_PACKET_LENGTH) {
- w.writeBytes(TestUtils.getRandomId());
- }
- if(tooBig) w.writeBytes(TestUtils.getRandomId());
- w.writeListEnd();
- assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
- return out.toByteArray();
- }
-
- private byte[] createEmptyOffer() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Writer w = writerFactory.createWriter(out);
- w.writeStructId(OFFER);
- w.writeListStart();
- w.writeListEnd();
- return out.toByteArray();
- }
-}
diff --git a/briar-tests/src/net/sf/briar/protocol/ProtocolReaderImplTest.java b/briar-tests/src/net/sf/briar/protocol/ProtocolReaderImplTest.java
new file mode 100644
index 000000000..15339e20b
--- /dev/null
+++ b/briar-tests/src/net/sf/briar/protocol/ProtocolReaderImplTest.java
@@ -0,0 +1,238 @@
+package net.sf.briar.protocol;
+
+import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
+import static net.sf.briar.api.protocol.Types.ACK;
+import static net.sf.briar.api.protocol.Types.OFFER;
+import static net.sf.briar.api.protocol.Types.REQUEST;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.BitSet;
+
+import net.sf.briar.BriarTestCase;
+import net.sf.briar.TestUtils;
+import net.sf.briar.api.FormatException;
+import net.sf.briar.api.protocol.Request;
+import net.sf.briar.api.serial.ReaderFactory;
+import net.sf.briar.api.serial.SerialComponent;
+import net.sf.briar.api.serial.Writer;
+import net.sf.briar.api.serial.WriterFactory;
+import net.sf.briar.serial.SerialModule;
+
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+public class ProtocolReaderImplTest extends BriarTestCase {
+
+ // FIXME: This is an integration test, not a unit test
+
+ private final SerialComponent serial;
+ private final ReaderFactory readerFactory;
+ private final WriterFactory writerFactory;
+
+ public ProtocolReaderImplTest() throws Exception {
+ super();
+ Injector i = Guice.createInjector(new SerialModule());
+ serial = i.getInstance(SerialComponent.class);
+ readerFactory = i.getInstance(ReaderFactory.class);
+ writerFactory = i.getInstance(WriterFactory.class);
+ }
+
+ @Test
+ public void testFormatExceptionIfAckIsTooLarge() throws Exception {
+ byte[] b = createAck(true);
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ try {
+ reader.readAck();
+ fail();
+ } catch(FormatException expected) {}
+ }
+
+ @Test
+ public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
+ byte[] b = createAck(false);
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ reader.readAck();
+ }
+
+ @Test
+ public void testEmptyAck() throws Exception {
+ byte[] b = createEmptyAck();
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ try {
+ reader.readAck();
+ fail();
+ } catch(FormatException expected) {}
+ }
+
+ @Test
+ public void testFormatExceptionIfOfferIsTooLarge() throws Exception {
+ byte[] b = createOffer(true);
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ try {
+ reader.readOffer();
+ fail();
+ } catch(FormatException expected) {}
+ }
+
+ @Test
+ public void testNoFormatExceptionIfOfferIsMaximumSize() throws Exception {
+ byte[] b = createOffer(false);
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ reader.readOffer();
+ }
+
+ @Test
+ public void testEmptyOffer() throws Exception {
+ byte[] b = createEmptyOffer();
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ try {
+ reader.readOffer();
+ fail();
+ } catch(FormatException expected) {}
+ }
+
+ @Test
+ public void testFormatExceptionIfRequestIsTooLarge() throws Exception {
+ byte[] b = createRequest(true);
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ try {
+ reader.readRequest();
+ fail();
+ } catch(FormatException expected) {}
+ }
+
+ @Test
+ public void testNoFormatExceptionIfRequestIsMaximumSize() throws Exception {
+ byte[] b = createRequest(false);
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory, null,
+ null, in);
+ reader.readRequest();
+ }
+
+ @Test
+ public void testBitmapDecoding() throws Exception {
+ // Test sizes from 0 to 1000 bits
+ for(int i = 0; i < 1000; i++) {
+ // Create a BitSet of size i with one in ten bits set (on average)
+ BitSet requested = new BitSet(i);
+ for(int j = 0; j < i; j++) if(Math.random() < 0.1) requested.set(j);
+ // Encode the BitSet as a bitmap
+ int bytes = i % 8 == 0 ? i / 8 : i / 8 + 1;
+ byte[] bitmap = new byte[bytes];
+ for(int j = 0; j < i; j++) {
+ if(requested.get(j)) {
+ int offset = j / 8;
+ byte bit = (byte) (128 >> j % 8);
+ bitmap[offset] |= bit;
+ }
+ }
+ // Create a serialised request containing the bitmap
+ byte[] b = createRequest(bitmap);
+ // Deserialise the request
+ ByteArrayInputStream in = new ByteArrayInputStream(b);
+ ProtocolReaderImpl reader = new ProtocolReaderImpl(readerFactory,
+ null, null, in);
+ Request request = reader.readRequest();
+ BitSet decoded = request.getBitmap();
+ // Check that the decoded BitSet matches the original - we can't
+ // use equals() because of padding, but the first i bits should
+ // match and the cardinalities should be equal, indicating that no
+ // padding bits are set
+ for(int j = 0; j < i; j++) {
+ assertEquals(requested.get(j), decoded.get(j));
+ }
+ assertEquals(requested.cardinality(), decoded.cardinality());
+ }
+ }
+
+ private byte[] createAck(boolean tooBig) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Writer w = writerFactory.createWriter(out);
+ w.writeStructId(ACK);
+ w.writeListStart();
+ while(out.size() + serial.getSerialisedUniqueIdLength()
+ < MAX_PACKET_LENGTH) {
+ w.writeBytes(TestUtils.getRandomId());
+ }
+ if(tooBig) w.writeBytes(TestUtils.getRandomId());
+ w.writeListEnd();
+ assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
+ return out.toByteArray();
+ }
+
+ private byte[] createEmptyAck() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Writer w = writerFactory.createWriter(out);
+ w.writeStructId(ACK);
+ w.writeListStart();
+ w.writeListEnd();
+ return out.toByteArray();
+ }
+
+ private byte[] createOffer(boolean tooBig) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Writer w = writerFactory.createWriter(out);
+ w.writeStructId(OFFER);
+ w.writeListStart();
+ while(out.size() + serial.getSerialisedUniqueIdLength()
+ < MAX_PACKET_LENGTH) {
+ w.writeBytes(TestUtils.getRandomId());
+ }
+ if(tooBig) w.writeBytes(TestUtils.getRandomId());
+ w.writeListEnd();
+ assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
+ return out.toByteArray();
+ }
+
+ private byte[] createEmptyOffer() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Writer w = writerFactory.createWriter(out);
+ w.writeStructId(OFFER);
+ w.writeListStart();
+ w.writeListEnd();
+ return out.toByteArray();
+ }
+
+ private byte[] createRequest(boolean tooBig) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Writer w = writerFactory.createWriter(out);
+ w.writeStructId(REQUEST);
+ // Allow one byte for the REQUEST tag, one byte for the padding length
+ // as a uint7, one byte for the BYTES tag, and five bytes for the
+ // length of the byte array as an int32
+ int size = MAX_PACKET_LENGTH - 8;
+ if(tooBig) size++;
+ assertTrue(size > Short.MAX_VALUE);
+ w.writeUint7((byte) 0);
+ w.writeBytes(new byte[size]);
+ assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
+ return out.toByteArray();
+ }
+
+ private byte[] createRequest(byte[] bitmap) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Writer w = writerFactory.createWriter(out);
+ w.writeStructId(REQUEST);
+ w.writeUint7((byte) 0);
+ w.writeBytes(bitmap);
+ return out.toByteArray();
+ }
+}
diff --git a/briar-tests/src/net/sf/briar/protocol/RequestReaderTest.java b/briar-tests/src/net/sf/briar/protocol/RequestReaderTest.java
deleted file mode 100644
index ec9d2746d..000000000
--- a/briar-tests/src/net/sf/briar/protocol/RequestReaderTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package net.sf.briar.protocol;
-
-import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
-import static net.sf.briar.api.protocol.Types.REQUEST;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.BitSet;
-
-import net.sf.briar.BriarTestCase;
-import net.sf.briar.api.FormatException;
-import net.sf.briar.api.protocol.Request;
-import net.sf.briar.api.serial.Reader;
-import net.sf.briar.api.serial.ReaderFactory;
-import net.sf.briar.api.serial.Writer;
-import net.sf.briar.api.serial.WriterFactory;
-import net.sf.briar.clock.ClockModule;
-import net.sf.briar.crypto.CryptoModule;
-import net.sf.briar.serial.SerialModule;
-
-import org.junit.Test;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-public class RequestReaderTest extends BriarTestCase {
-
- // FIXME: This is an integration test, not a unit test
-
- private final ReaderFactory readerFactory;
- private final WriterFactory writerFactory;
-
- public RequestReaderTest() throws Exception {
- super();
- Injector i = Guice.createInjector(new ClockModule(), new CryptoModule(),
- new ProtocolModule(), new SerialModule());
- readerFactory = i.getInstance(ReaderFactory.class);
- writerFactory = i.getInstance(WriterFactory.class);
- }
-
- @Test
- public void testFormatExceptionIfRequestIsTooLarge() throws Exception {
- byte[] b = createRequest(true);
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(REQUEST, new RequestReader());
- try {
- reader.readStruct(REQUEST, Request.class);
- fail();
- } catch(FormatException expected) {}
- }
-
- @Test
- public void testNoFormatExceptionIfRequestIsMaximumSize() throws Exception {
- byte[] b = createRequest(false);
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- reader.addStructReader(REQUEST, new RequestReader());
- reader.readStruct(REQUEST, Request.class);
- }
-
- @Test
- public void testBitmapDecoding() throws Exception {
- // Test sizes from 0 to 1000 bits
- for(int i = 0; i < 1000; i++) {
- // Create a BitSet of size i with one in ten bits set (on average)
- BitSet requested = new BitSet(i);
- for(int j = 0; j < i; j++) if(Math.random() < 0.1) requested.set(j);
- // Encode the BitSet as a bitmap
- int bytes = i % 8 == 0 ? i / 8 : i / 8 + 1;
- byte[] bitmap = new byte[bytes];
- for(int j = 0; j < i; j++) {
- if(requested.get(j)) {
- int offset = j / 8;
- byte bit = (byte) (128 >> j % 8);
- bitmap[offset] |= bit;
- }
- }
- // Create a serialised request containing the bitmap
- byte[] b = createRequest(bitmap);
- // Deserialise the request
- ByteArrayInputStream in = new ByteArrayInputStream(b);
- Reader reader = readerFactory.createReader(in);
- RequestReader requestReader = new RequestReader();
- reader.addStructReader(REQUEST, requestReader);
- Request r = reader.readStruct(REQUEST, Request.class);
- BitSet decoded = r.getBitmap();
- // Check that the decoded BitSet matches the original - we can't
- // use equals() because of padding, but the first i bits should
- // match and the cardinalities should be equal, indicating that no
- // padding bits are set
- for(int j = 0; j < i; j++) {
- assertEquals(requested.get(j), decoded.get(j));
- }
- assertEquals(requested.cardinality(), decoded.cardinality());
- }
- }
-
- private byte[] createRequest(boolean tooBig) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Writer w = writerFactory.createWriter(out);
- w.writeStructId(REQUEST);
- // Allow one byte for the REQUEST tag, one byte for the padding length
- // as a uint7, one byte for the BYTES tag, and five bytes for the
- // length of the byte array as an int32
- int size = MAX_PACKET_LENGTH - 8;
- if(tooBig) size++;
- assertTrue(size > Short.MAX_VALUE);
- w.writeUint7((byte) 0);
- w.writeBytes(new byte[size]);
- assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
- return out.toByteArray();
- }
-
- private byte[] createRequest(byte[] bitmap) throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Writer w = writerFactory.createWriter(out);
- w.writeStructId(REQUEST);
- w.writeUint7((byte) 0);
- w.writeBytes(bitmap);
- return out.toByteArray();
- }
-}