diff --git a/api/net/sf/briar/api/protocol/Tags.java b/api/net/sf/briar/api/protocol/Tags.java index 59726ca5accd0c1980482312ecc60bec8c2ccdc7..3b0071d4cae947cc6d5c4a486ac6f8f12cbd30eb 100644 --- a/api/net/sf/briar/api/protocol/Tags.java +++ b/api/net/sf/briar/api/protocol/Tags.java @@ -16,6 +16,8 @@ public interface Tags { static final int GROUP_ID = 6; static final int MESSAGE = 7; static final int MESSAGE_ID = 8; - static final int SUBSCRIPTIONS = 9; - static final int TRANSPORTS = 10; + static final int OFFER = 9; + static final int REQUEST = 10; + static final int SUBSCRIPTIONS = 11; + static final int TRANSPORTS = 12; } diff --git a/api/net/sf/briar/api/protocol/writers/PacketWriterFactory.java b/api/net/sf/briar/api/protocol/writers/PacketWriterFactory.java index ac4d3c292c2999127c1fe7de7fe68465cfd1a45d..71699b8ad306987d7a28f73f178e4ab778488872 100644 --- a/api/net/sf/briar/api/protocol/writers/PacketWriterFactory.java +++ b/api/net/sf/briar/api/protocol/writers/PacketWriterFactory.java @@ -8,6 +8,10 @@ public interface PacketWriterFactory { BatchWriter createBatchWriter(OutputStream out); + OfferWriter createOfferWriter(OutputStream out); + + RequestWriter createRequestWriter(OutputStream out); + SubscriptionWriter createSubscriptionWriter(OutputStream out); TransportWriter createTransportWriter(OutputStream out); diff --git a/api/net/sf/briar/api/protocol/writers/RequestWriter.java b/api/net/sf/briar/api/protocol/writers/RequestWriter.java index 2dd52d2fbfb9ebf30227e7ba667728113763e1df..335753f6c2ddcf2f7b4625e3deb427c99a3dbc4d 100644 --- a/api/net/sf/briar/api/protocol/writers/RequestWriter.java +++ b/api/net/sf/briar/api/protocol/writers/RequestWriter.java @@ -7,5 +7,5 @@ import java.util.BitSet; public interface RequestWriter { /** Writes the contents of the request. */ - void writeBitmap(BitSet b) throws IOException; + void writeBitmap(BitSet b, int length) throws IOException; } diff --git a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java index 2ccb63d1da73ea1ec87c09ad32077a04f85f538d..de0139a6f24451961f045e5a63c5a9340dab376d 100644 --- a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java +++ b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java @@ -676,11 +676,10 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { try { subscriptionLock.readLock().lock(); try { - BitSet request; + Collection<MessageId> offered = o.getMessages(); + BitSet request = new BitSet(offered.size()); Txn txn = db.startTransaction(); try { - Collection<MessageId> offered = o.getMessages(); - request = new BitSet(offered.size()); Iterator<MessageId> it = offered.iterator(); for(int i = 0; it.hasNext(); i++) { // If the message is not in the database, or if @@ -694,7 +693,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { db.abortTransaction(txn); throw e; } - r.writeBitmap(request); + r.writeBitmap(request, offered.size()); } finally { subscriptionLock.readLock().unlock(); } diff --git a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java index c6fd5e706fb9d0dea65f9d4ce8c7935b66ad0840..079ef8254c6c4a6d810b365f4bc8defe5d7effb9 100644 --- a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java +++ b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java @@ -497,11 +497,10 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { synchronized(messageLock) { synchronized(messageStatusLock) { synchronized(subscriptionLock) { - BitSet request; + Collection<MessageId> offered = o.getMessages(); + BitSet request = new BitSet(offered.size()); Txn txn = db.startTransaction(); try { - Collection<MessageId> offered = o.getMessages(); - request = new BitSet(offered.size()); Iterator<MessageId> it = offered.iterator(); for(int i = 0; it.hasNext(); i++) { // If the message is not in the database, or if @@ -515,7 +514,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { db.abortTransaction(txn); throw e; } - r.writeBitmap(request); + r.writeBitmap(request, offered.size()); } } } diff --git a/components/net/sf/briar/protocol/AckReader.java b/components/net/sf/briar/protocol/AckReader.java index 93c88fc8ab7277bf3d3911669a7201982df7f6d7..bffaa76c16e3cf565f26fdaee047e748aa4ccaf3 100644 --- a/components/net/sf/briar/protocol/AckReader.java +++ b/components/net/sf/briar/protocol/AckReader.java @@ -9,11 +9,14 @@ import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; +import com.google.inject.Inject; + class AckReader implements ObjectReader<Ack> { private final ObjectReader<BatchId> batchIdReader; private final AckFactory ackFactory; + @Inject AckReader(ObjectReader<BatchId> batchIdReader, AckFactory ackFactory) { this.batchIdReader = batchIdReader; this.ackFactory = ackFactory; diff --git a/components/net/sf/briar/protocol/AuthorReader.java b/components/net/sf/briar/protocol/AuthorReader.java index 7988f0d59f3cf5d428695811a568e12f4153c945..8a25ffc178769fd435acf5b3bf1dc4078b76bcbb 100644 --- a/components/net/sf/briar/protocol/AuthorReader.java +++ b/components/net/sf/briar/protocol/AuthorReader.java @@ -11,11 +11,14 @@ import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; +import com.google.inject.Inject; + class AuthorReader implements ObjectReader<Author> { private final MessageDigest messageDigest; private final AuthorFactory authorFactory; + @Inject AuthorReader(CryptoComponent crypto, AuthorFactory authorFactory) { messageDigest = crypto.getMessageDigest(); this.authorFactory = authorFactory; diff --git a/components/net/sf/briar/protocol/BatchReader.java b/components/net/sf/briar/protocol/BatchReader.java index 4b467e0304ddf5819e30b6601fe0f4b3096529a4..95b3ae3446087916241410e42f6f825ef81cd700 100644 --- a/components/net/sf/briar/protocol/BatchReader.java +++ b/components/net/sf/briar/protocol/BatchReader.java @@ -12,12 +12,15 @@ import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; +import com.google.inject.Inject; + class BatchReader implements ObjectReader<Batch> { private final MessageDigest messageDigest; private final ObjectReader<Message> messageReader; private final BatchFactory batchFactory; + @Inject BatchReader(CryptoComponent crypto, ObjectReader<Message> messageReader, BatchFactory batchFactory) { messageDigest = crypto.getMessageDigest(); diff --git a/components/net/sf/briar/protocol/GroupReader.java b/components/net/sf/briar/protocol/GroupReader.java index ceadff74bd702c5fa0ff0d2c474bfd8c89f61670..ef2d4b9d739514e089f3453498640da1b662e30d 100644 --- a/components/net/sf/briar/protocol/GroupReader.java +++ b/components/net/sf/briar/protocol/GroupReader.java @@ -11,11 +11,14 @@ import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; +import com.google.inject.Inject; + class GroupReader implements ObjectReader<Group> { private final MessageDigest messageDigest; private final GroupFactory groupFactory; + @Inject GroupReader(CryptoComponent crypto, GroupFactory groupFactory) { messageDigest = crypto.getMessageDigest(); this.groupFactory = groupFactory; diff --git a/components/net/sf/briar/protocol/MessageReader.java b/components/net/sf/briar/protocol/MessageReader.java index d80a6dfa5cee7ef5b6aabe2513acb8ee7928ab71..bc206e00b4e9f72b2957fb6fb0714ae7076b0374 100644 --- a/components/net/sf/briar/protocol/MessageReader.java +++ b/components/net/sf/briar/protocol/MessageReader.java @@ -19,6 +19,8 @@ import net.sf.briar.api.serial.FormatException; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; +import com.google.inject.Inject; + class MessageReader implements ObjectReader<Message> { private final ObjectReader<Group> groupReader; @@ -27,6 +29,7 @@ class MessageReader implements ObjectReader<Message> { private final Signature signature; private final MessageDigest messageDigest; + @Inject MessageReader(CryptoComponent crypto, ObjectReader<Group> groupReader, ObjectReader<Author> authorReader) { this.groupReader = groupReader; diff --git a/components/net/sf/briar/protocol/ProtocolModule.java b/components/net/sf/briar/protocol/ProtocolModule.java index 09c45dfb16f216cbd0b90965ce48717e89ad203d..c5ea605579b52f2e1ff580b0b50423b08bf4520a 100644 --- a/components/net/sf/briar/protocol/ProtocolModule.java +++ b/components/net/sf/briar/protocol/ProtocolModule.java @@ -1,10 +1,17 @@ package net.sf.briar.protocol; +import net.sf.briar.api.crypto.CryptoComponent; +import net.sf.briar.api.protocol.Author; import net.sf.briar.api.protocol.AuthorFactory; +import net.sf.briar.api.protocol.BatchId; +import net.sf.briar.api.protocol.Group; import net.sf.briar.api.protocol.GroupFactory; +import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.MessageEncoder; +import net.sf.briar.api.serial.ObjectReader; import com.google.inject.AbstractModule; +import com.google.inject.Provides; public class ProtocolModule extends AbstractModule { @@ -14,6 +21,32 @@ public class ProtocolModule extends AbstractModule { bind(AuthorFactory.class).to(AuthorFactoryImpl.class); bind(BatchFactory.class).to(BatchFactoryImpl.class); bind(GroupFactory.class).to(GroupFactoryImpl.class); + bind(SubscriptionFactory.class).to(SubscriptionFactoryImpl.class); + bind(TransportFactory.class).to(TransportFactoryImpl.class); bind(MessageEncoder.class).to(MessageEncoderImpl.class); } + + @Provides + ObjectReader<BatchId> getBatchIdReader() { + return new BatchIdReader(); + } + + @Provides + ObjectReader<Group> getGroupReader(CryptoComponent crypto, + GroupFactory groupFactory) { + return new GroupReader(crypto, groupFactory); + } + + @Provides + ObjectReader<Author> getAuthorReader(CryptoComponent crypto, + AuthorFactory authorFactory) { + return new AuthorReader(crypto, authorFactory); + } + + @Provides + ObjectReader<Message> getMessageReader(CryptoComponent crypto, + ObjectReader<Group> groupReader, + ObjectReader<Author> authorReader) { + return new MessageReader(crypto, groupReader, authorReader); + } } diff --git a/components/net/sf/briar/protocol/SubscriptionReader.java b/components/net/sf/briar/protocol/SubscriptionReader.java index e4902137111d8d240856c37d2c7888a1882d9129..88a693b26a7a95284109eb3f9ade39c94b608a8e 100644 --- a/components/net/sf/briar/protocol/SubscriptionReader.java +++ b/components/net/sf/briar/protocol/SubscriptionReader.java @@ -9,11 +9,14 @@ import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; +import com.google.inject.Inject; + class SubscriptionReader implements ObjectReader<Subscriptions> { private final ObjectReader<Group> groupReader; private final SubscriptionFactory subscriptionFactory; + @Inject SubscriptionReader(ObjectReader<Group> groupReader, SubscriptionFactory subscriptionFactory) { this.groupReader = groupReader; diff --git a/components/net/sf/briar/protocol/TransportReader.java b/components/net/sf/briar/protocol/TransportReader.java index 580d0ffd47d1a4289a9dd55a7d3b216b9e022611..41d5f21f6f10ed42216d79bdee6b1dbc0285f992 100644 --- a/components/net/sf/briar/protocol/TransportReader.java +++ b/components/net/sf/briar/protocol/TransportReader.java @@ -8,10 +8,13 @@ import net.sf.briar.api.protocol.Transports; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; +import com.google.inject.Inject; + class TransportReader implements ObjectReader<Transports> { private final TransportFactory transportFactory; + @Inject TransportReader(TransportFactory transportFactory) { this.transportFactory = transportFactory; } diff --git a/components/net/sf/briar/protocol/writers/AckWriterImpl.java b/components/net/sf/briar/protocol/writers/AckWriterImpl.java index fbc854f0feb2f6d8f7f4cf858fc76b4eda42f4cd..6d3648c214a4f692aeb5cb01d82b7f33f483b6d1 100644 --- a/components/net/sf/briar/protocol/writers/AckWriterImpl.java +++ b/components/net/sf/briar/protocol/writers/AckWriterImpl.java @@ -15,7 +15,7 @@ class AckWriterImpl implements AckWriter { private final OutputStream out; private final Writer w; - private boolean started = false, finished = false; + private boolean started = false; AckWriterImpl(OutputStream out, WriterFactory writerFactory) { this.out = out; @@ -23,7 +23,6 @@ class AckWriterImpl implements AckWriter { } public boolean writeBatchId(BatchId b) throws IOException { - if(finished) throw new IllegalStateException(); if(!started) { w.writeUserDefinedTag(Tags.ACK); w.writeListStart(); @@ -36,7 +35,6 @@ class AckWriterImpl implements AckWriter { } public void finish() throws IOException { - if(finished) throw new IllegalStateException(); if(!started) { w.writeUserDefinedTag(Tags.ACK); w.writeListStart(); @@ -44,6 +42,6 @@ class AckWriterImpl implements AckWriter { } w.writeListEnd(); out.flush(); - finished = true; + started = false; } } diff --git a/components/net/sf/briar/protocol/writers/BatchWriterImpl.java b/components/net/sf/briar/protocol/writers/BatchWriterImpl.java index 1c026127f0f758f099d5ce89d737af20c1d25484..e0c518642062210a8dd5b87e2c519c2180f4354d 100644 --- a/components/net/sf/briar/protocol/writers/BatchWriterImpl.java +++ b/components/net/sf/briar/protocol/writers/BatchWriterImpl.java @@ -18,7 +18,7 @@ class BatchWriterImpl implements BatchWriter { private final Writer w; private final MessageDigest messageDigest; - private boolean started = false, finished = false; + private boolean started = false; BatchWriterImpl(OutputStream out, WriterFactory writerFactory, MessageDigest messageDigest) { @@ -32,7 +32,6 @@ class BatchWriterImpl implements BatchWriter { } public boolean writeMessage(byte[] message) throws IOException { - if(finished) throw new IllegalStateException(); if(!started) { messageDigest.reset(); w.writeUserDefinedTag(Tags.BATCH); @@ -47,7 +46,6 @@ class BatchWriterImpl implements BatchWriter { } public BatchId finish() throws IOException { - if(finished) throw new IllegalStateException(); if(!started) { messageDigest.reset(); w.writeUserDefinedTag(Tags.BATCH); @@ -56,7 +54,7 @@ class BatchWriterImpl implements BatchWriter { } w.writeListEnd(); out.flush(); - finished = true; + 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 new file mode 100644 index 0000000000000000000000000000000000000000..c0ec46fe94dbd01d5c6f43845fc5fbe35f5ee761 --- /dev/null +++ b/components/net/sf/briar/protocol/writers/OfferWriterImpl.java @@ -0,0 +1,49 @@ +package net.sf.briar.protocol.writers; + +import java.io.IOException; +import java.io.OutputStream; + +import net.sf.briar.api.protocol.MessageId; +import net.sf.briar.api.protocol.Offer; +import net.sf.briar.api.protocol.Tags; +import net.sf.briar.api.protocol.writers.OfferWriter; +import net.sf.briar.api.serial.Writer; +import net.sf.briar.api.serial.WriterFactory; + +class OfferWriterImpl implements OfferWriter { + + private final OutputStream out; + private final Writer w; + + private boolean started = false, finished = false; + + OfferWriterImpl(OutputStream out, WriterFactory writerFactory) { + this.out = out; + w = writerFactory.createWriter(out); + } + + public boolean writeMessageId(MessageId m) throws IOException { + if(finished) throw new IllegalStateException(); + if(!started) { + w.writeUserDefinedTag(Tags.OFFER); + w.writeListStart(); + started = true; + } + int capacity = Offer.MAX_SIZE - (int) w.getBytesWritten() - 1; + if(capacity < MessageId.SERIALISED_LENGTH) return false; + m.writeTo(w); + return true; + } + + public void finish() throws IOException { + if(finished) throw new IllegalStateException(); + if(!started) { + w.writeUserDefinedTag(Tags.OFFER); + w.writeListStart(); + started = true; + } + w.writeListEnd(); + out.flush(); + finished = true; + } +} diff --git a/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java b/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java index 7d0959db5460ecee61f651e1ff25f90eafe9bf3b..5daaf2361a8145817193b186bdd0172f51917d2e 100644 --- a/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java +++ b/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java @@ -6,7 +6,9 @@ import java.security.MessageDigest; import net.sf.briar.api.crypto.CryptoComponent; import net.sf.briar.api.protocol.writers.AckWriter; import net.sf.briar.api.protocol.writers.BatchWriter; +import net.sf.briar.api.protocol.writers.OfferWriter; import net.sf.briar.api.protocol.writers.PacketWriterFactory; +import net.sf.briar.api.protocol.writers.RequestWriter; import net.sf.briar.api.protocol.writers.SubscriptionWriter; import net.sf.briar.api.protocol.writers.TransportWriter; import net.sf.briar.api.serial.WriterFactory; @@ -33,6 +35,14 @@ class PacketWriterFactoryImpl implements PacketWriterFactory { return new BatchWriterImpl(out, writerFactory, messageDigest); } + public OfferWriter createOfferWriter(OutputStream out) { + return new OfferWriterImpl(out, writerFactory); + } + + public RequestWriter createRequestWriter(OutputStream out) { + return new RequestWriterImpl(out, writerFactory); + } + public SubscriptionWriter createSubscriptionWriter(OutputStream out) { return new SubscriptionWriterImpl(out, writerFactory); } diff --git a/components/net/sf/briar/protocol/writers/RequestWriterImpl.java b/components/net/sf/briar/protocol/writers/RequestWriterImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..28bce226a28ac08e43d0eac325d98deffe3a613d --- /dev/null +++ b/components/net/sf/briar/protocol/writers/RequestWriterImpl.java @@ -0,0 +1,38 @@ +package net.sf.briar.protocol.writers; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.BitSet; + +import net.sf.briar.api.protocol.Tags; +import net.sf.briar.api.protocol.writers.RequestWriter; +import net.sf.briar.api.serial.Writer; +import net.sf.briar.api.serial.WriterFactory; + +class RequestWriterImpl implements RequestWriter { + + private final OutputStream out; + private final Writer w; + + RequestWriterImpl(OutputStream out, WriterFactory writerFactory) { + this.out = out; + w = writerFactory.createWriter(out); + } + + public void writeBitmap(BitSet b, int length) throws IOException { + w.writeUserDefinedTag(Tags.REQUEST); + // If the number of bits isn't a multiple of 8, round up to a byte + int bytes = length % 8 == 0 ? length / 8 : length / 8 + 1; + byte[] bitmap = new byte[bytes]; + // I'm kind of surprised BitSet doesn't have a method for this + for(int i = 0; i < length; i++) { + if(b.get(i)) { + int offset = i / 8; + byte bit = (byte) (128 >> i % 8); + bitmap[offset] |= bit; + } + } + w.writeBytes(bitmap); + out.flush(); + } +} diff --git a/components/net/sf/briar/protocol/writers/SubscriptionWriterImpl.java b/components/net/sf/briar/protocol/writers/SubscriptionWriterImpl.java index ad4f6081bdeb9567fd78f386378388f77a7a1f32..67e5736c2ae0fab17a4510f53d71a2bfe77f4665 100644 --- a/components/net/sf/briar/protocol/writers/SubscriptionWriterImpl.java +++ b/components/net/sf/briar/protocol/writers/SubscriptionWriterImpl.java @@ -15,19 +15,15 @@ class SubscriptionWriterImpl implements SubscriptionWriter { private final OutputStream out; private final Writer w; - private boolean used = false; - SubscriptionWriterImpl(OutputStream out, WriterFactory writerFactory) { this.out = out; w = writerFactory.createWriter(out); } public void writeSubscriptions(Collection<Group> subs) throws IOException { - if(used) throw new IllegalStateException(); w.writeUserDefinedTag(Tags.SUBSCRIPTIONS); w.writeList(subs); w.writeInt64(System.currentTimeMillis()); out.flush(); - used = true; } } diff --git a/components/net/sf/briar/protocol/writers/TransportWriterImpl.java b/components/net/sf/briar/protocol/writers/TransportWriterImpl.java index 0bcca53c541a6137a35a4f0d87538307abf63329..495e001b937d7363e7b6ef23b8eb3c9fe69f5b60 100644 --- a/components/net/sf/briar/protocol/writers/TransportWriterImpl.java +++ b/components/net/sf/briar/protocol/writers/TransportWriterImpl.java @@ -14,8 +14,6 @@ class TransportWriterImpl implements TransportWriter { private final OutputStream out; private final Writer w; - private boolean used = false; - TransportWriterImpl(OutputStream out, WriterFactory writerFactory) { this.out = out; w = writerFactory.createWriter(out); @@ -23,11 +21,9 @@ class TransportWriterImpl implements TransportWriter { public void writeTransports(Map<String, String> transports) throws IOException { - if(used) throw new IllegalStateException(); w.writeUserDefinedTag(Tags.TRANSPORTS); w.writeMap(transports); w.writeInt64(System.currentTimeMillis()); out.flush(); - used = true; } } diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java index 32faacbb12a198f8d64b2776ca50b4ec977f5cb0..6f843d19116ee71369242eb609e21a987c1b706e 100644 --- a/test/net/sf/briar/db/DatabaseComponentTest.java +++ b/test/net/sf/briar/db/DatabaseComponentTest.java @@ -948,7 +948,7 @@ public abstract class DatabaseComponentTest extends TestCase { will(returnValue(true)); // Visible - do not request message # 1 oneOf(database).setStatusSeenIfVisible(txn, contactId, messageId2); will(returnValue(false)); // Not visible - request message # 2 - oneOf(requestWriter).writeBitmap(expectedRequest); + oneOf(requestWriter).writeBitmap(expectedRequest, 3); }}); DatabaseComponent db = createDatabaseComponent(database, cleaner); diff --git a/test/net/sf/briar/protocol/FileReadWriteTest.java b/test/net/sf/briar/protocol/FileReadWriteTest.java index 4fe36afc2320d5f0578a213e9a8276e06ac5e4d8..695008fa5b3e9b7d15cde8a31facc7d693f19d33 100644 --- a/test/net/sf/briar/protocol/FileReadWriteTest.java +++ b/test/net/sf/briar/protocol/FileReadWriteTest.java @@ -34,7 +34,6 @@ import net.sf.briar.api.protocol.writers.SubscriptionWriter; import net.sf.briar.api.protocol.writers.TransportWriter; import net.sf.briar.api.serial.Reader; import net.sf.briar.api.serial.ReaderFactory; -import net.sf.briar.api.serial.WriterFactory; import net.sf.briar.crypto.CryptoModule; import net.sf.briar.protocol.writers.WritersModule; import net.sf.briar.serial.SerialModule; @@ -55,9 +54,12 @@ public class FileReadWriteTest extends TestCase { private final long start = System.currentTimeMillis(); private final ReaderFactory readerFactory; - private final WriterFactory writerFactory; private final PacketWriterFactory packetWriterFactory; private final CryptoComponent crypto; + private final AckReader ackReader; + private final BatchReader batchReader; + private final SubscriptionReader subscriptionReader; + private final TransportReader transportReader; private final Author author; private final Group group, group1; private final Message message, message1, message2, message3; @@ -70,11 +72,14 @@ public class FileReadWriteTest extends TestCase { new ProtocolModule(), new SerialModule(), new WritersModule()); readerFactory = i.getInstance(ReaderFactory.class); - writerFactory = i.getInstance(WriterFactory.class); packetWriterFactory = i.getInstance(PacketWriterFactory.class); crypto = i.getInstance(CryptoComponent.class); assertEquals(crypto.getMessageDigest().getDigestLength(), UniqueId.LENGTH); + ackReader = i.getInstance(AckReader.class); + batchReader = i.getInstance(BatchReader.class); + subscriptionReader = i.getInstance(SubscriptionReader.class); + transportReader = i.getInstance(TransportReader.class); // Create two groups: one restricted, one unrestricted GroupFactory groupFactory = i.getInstance(GroupFactory.class); group = groupFactory.createGroup("Unrestricted group", null); @@ -139,21 +144,6 @@ public class FileReadWriteTest extends TestCase { testWriteFile(); - GroupReader groupReader = new GroupReader(crypto, - new GroupFactoryImpl(crypto, writerFactory)); - AuthorReader authorReader = new AuthorReader(crypto, - new AuthorFactoryImpl(crypto, writerFactory)); - MessageReader messageReader = new MessageReader(crypto, groupReader, - authorReader); - AckReader ackReader = new AckReader(new BatchIdReader(), - new AckFactoryImpl()); - BatchReader batchReader = new BatchReader(crypto, messageReader, - new BatchFactoryImpl()); - SubscriptionReader subscriptionReader = - new SubscriptionReader(groupReader, new SubscriptionFactoryImpl()); - TransportReader transportReader = - new TransportReader(new TransportFactoryImpl()); - FileInputStream in = new FileInputStream(file); Reader reader = readerFactory.createReader(in); reader.addObjectReader(Tags.ACK, ackReader); diff --git a/test/net/sf/briar/protocol/writers/RequestWriterImplTest.java b/test/net/sf/briar/protocol/writers/RequestWriterImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b612f95bb14873d902898a81ebf568b7caea1226 --- /dev/null +++ b/test/net/sf/briar/protocol/writers/RequestWriterImplTest.java @@ -0,0 +1,70 @@ +package net.sf.briar.protocol.writers; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.BitSet; + +import junit.framework.TestCase; +import net.sf.briar.api.protocol.writers.RequestWriter; +import net.sf.briar.api.serial.WriterFactory; +import net.sf.briar.serial.SerialModule; +import net.sf.briar.util.StringUtils; + +import org.junit.Test; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class RequestWriterImplTest extends TestCase { + + private final WriterFactory writerFactory; + + public RequestWriterImplTest() { + super(); + Injector i = Guice.createInjector(new SerialModule()); + writerFactory = i.getInstance(WriterFactory.class); + } + + @Test + public void testWriteBitmapNoPadding() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + RequestWriter r = new RequestWriterImpl(out, writerFactory); + BitSet b = new BitSet(); + // 11011001 = 0xD9 + b.set(0); + b.set(1); + b.set(3); + b.set(4); + b.set(7); + // 01011001 = 0x59 + b.set(9); + b.set(11); + b.set(12); + b.set(15); + r.writeBitmap(b, 16); + // Short user tag 10, short bytes with length 2, 0xD959 + byte[] output = out.toByteArray(); + assertEquals("CA" + "92" + "D959", StringUtils.toHexString(output)); + } + + @Test + public void testWriteBitmapWithPadding() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + RequestWriter r = new RequestWriterImpl(out, writerFactory); + BitSet b = new BitSet(); + // 01011001 = 0x59 + b.set(1); + b.set(3); + b.set(4); + b.set(7); + // 11011xxx = 0xD8, after padding + b.set(8); + b.set(9); + b.set(11); + b.set(12); + r.writeBitmap(b, 13); + // Short user tag 10, short bytes with length 2, 0x59D8 + byte[] output = out.toByteArray(); + assertEquals("CA" + "92" + "59D8", StringUtils.toHexString(output)); + } +}