diff --git a/components/net/sf/briar/protocol/AckReader.java b/components/net/sf/briar/protocol/AckReader.java index bffaa76c16e3cf565f26fdaee047e748aa4ccaf3..77ba91d23d1212333d4c5380c2792de84e241631 100644 --- a/components/net/sf/briar/protocol/AckReader.java +++ b/components/net/sf/briar/protocol/AckReader.java @@ -6,6 +6,7 @@ import java.util.Collection; import net.sf.briar.api.protocol.Ack; import net.sf.briar.api.protocol.BatchId; import net.sf.briar.api.protocol.Tags; +import net.sf.briar.api.serial.Consumer; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; @@ -24,7 +25,7 @@ class AckReader implements ObjectReader<Ack> { public Ack readObject(Reader r) throws IOException { // Initialise the consumer - CountingConsumer counting = new CountingConsumer(Ack.MAX_SIZE); + Consumer counting = new CountingConsumer(Ack.MAX_SIZE); // Read and digest the data r.addConsumer(counting); r.readUserDefinedTag(Tags.ACK); diff --git a/components/net/sf/briar/protocol/BatchReader.java b/components/net/sf/briar/protocol/BatchReader.java index 95b3ae3446087916241410e42f6f825ef81cd700..15ccb655cd310cd41be88130a5459f90727ca49d 100644 --- a/components/net/sf/briar/protocol/BatchReader.java +++ b/components/net/sf/briar/protocol/BatchReader.java @@ -9,6 +9,7 @@ import net.sf.briar.api.protocol.Batch; import net.sf.briar.api.protocol.BatchId; import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Tags; +import net.sf.briar.api.serial.Consumer; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; @@ -30,7 +31,7 @@ class BatchReader implements ObjectReader<Batch> { public Batch readObject(Reader r) throws IOException { // Initialise the consumers - CountingConsumer counting = new CountingConsumer(Batch.MAX_SIZE); + Consumer counting = new CountingConsumer(Batch.MAX_SIZE); DigestingConsumer digesting = new DigestingConsumer(messageDigest); messageDigest.reset(); // Read and digest the data diff --git a/components/net/sf/briar/protocol/MessageIdReader.java b/components/net/sf/briar/protocol/MessageIdReader.java new file mode 100644 index 0000000000000000000000000000000000000000..118bf0ea484065d0ccb429938086361d361f28ee --- /dev/null +++ b/components/net/sf/briar/protocol/MessageIdReader.java @@ -0,0 +1,20 @@ +package net.sf.briar.protocol; + +import java.io.IOException; + +import net.sf.briar.api.protocol.MessageId; +import net.sf.briar.api.protocol.Tags; +import net.sf.briar.api.protocol.UniqueId; +import net.sf.briar.api.serial.FormatException; +import net.sf.briar.api.serial.ObjectReader; +import net.sf.briar.api.serial.Reader; + +class MessageIdReader implements ObjectReader<MessageId> { + + public MessageId readObject(Reader r) throws IOException { + r.readUserDefinedTag(Tags.MESSAGE_ID); + byte[] b = r.readBytes(); + if(b.length != UniqueId.LENGTH) throw new FormatException(); + return new MessageId(b); + } +} diff --git a/components/net/sf/briar/protocol/MessageReader.java b/components/net/sf/briar/protocol/MessageReader.java index bc206e00b4e9f72b2957fb6fb0714ae7076b0374..ef71831285afc77942f08fbd69134af6c6649506 100644 --- a/components/net/sf/briar/protocol/MessageReader.java +++ b/components/net/sf/briar/protocol/MessageReader.java @@ -14,7 +14,6 @@ import net.sf.briar.api.protocol.Group; import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.Tags; -import net.sf.briar.api.protocol.UniqueId; import net.sf.briar.api.serial.FormatException; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; @@ -23,6 +22,7 @@ import com.google.inject.Inject; class MessageReader implements ObjectReader<Message> { + private final ObjectReader<MessageId> messageIdReader; private final ObjectReader<Group> groupReader; private final ObjectReader<Author> authorReader; private final KeyParser keyParser; @@ -30,8 +30,11 @@ class MessageReader implements ObjectReader<Message> { private final MessageDigest messageDigest; @Inject - MessageReader(CryptoComponent crypto, ObjectReader<Group> groupReader, + MessageReader(CryptoComponent crypto, + ObjectReader<MessageId> messageIdReader, + ObjectReader<Group> groupReader, ObjectReader<Author> authorReader) { + this.messageIdReader = messageIdReader; this.groupReader = groupReader; this.authorReader = authorReader; keyParser = crypto.getKeyParser(); @@ -47,10 +50,9 @@ class MessageReader implements ObjectReader<Message> { // Read the initial tag r.readUserDefinedTag(Tags.MESSAGE); // Read the parent's message ID - r.readUserDefinedTag(Tags.MESSAGE_ID); - byte[] b = r.readBytes(); - if(b.length != UniqueId.LENGTH) throw new FormatException(); - MessageId parent = new MessageId(b); + r.addObjectReader(Tags.MESSAGE_ID, messageIdReader); + MessageId parent = r.readUserDefined(Tags.MESSAGE_ID, MessageId.class); + r.removeObjectReader(Tags.MESSAGE_ID); // Read the group r.addObjectReader(Tags.GROUP, groupReader); Group group = r.readUserDefined(Tags.GROUP, Group.class); diff --git a/components/net/sf/briar/protocol/OfferFactory.java b/components/net/sf/briar/protocol/OfferFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..23fbea52d438578072dcaa7142c0d9e4fb9c15b1 --- /dev/null +++ b/components/net/sf/briar/protocol/OfferFactory.java @@ -0,0 +1,11 @@ +package net.sf.briar.protocol; + +import java.util.Collection; + +import net.sf.briar.api.protocol.MessageId; +import net.sf.briar.api.protocol.Offer; + +interface OfferFactory { + + Offer createOffer(Collection<MessageId> messages); +} diff --git a/components/net/sf/briar/protocol/OfferFactoryImpl.java b/components/net/sf/briar/protocol/OfferFactoryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..8635b0b96adf24738f3b3f2080c3616ade4e8d62 --- /dev/null +++ b/components/net/sf/briar/protocol/OfferFactoryImpl.java @@ -0,0 +1,13 @@ +package net.sf.briar.protocol; + +import java.util.Collection; + +import net.sf.briar.api.protocol.MessageId; +import net.sf.briar.api.protocol.Offer; + +class OfferFactoryImpl implements OfferFactory { + + public Offer createOffer(Collection<MessageId> messages) { + return new OfferImpl(messages); + } +} diff --git a/components/net/sf/briar/protocol/OfferImpl.java b/components/net/sf/briar/protocol/OfferImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..129d2054e5e68eb78edbc1ac4bf3cf3e1102ff2f --- /dev/null +++ b/components/net/sf/briar/protocol/OfferImpl.java @@ -0,0 +1,19 @@ +package net.sf.briar.protocol; + +import java.util.Collection; + +import net.sf.briar.api.protocol.MessageId; +import net.sf.briar.api.protocol.Offer; + +class OfferImpl implements Offer { + + private final Collection<MessageId> messages; + + OfferImpl(Collection<MessageId> messages) { + this.messages = messages; + } + + public Collection<MessageId> getMessages() { + return messages; + } +} diff --git a/components/net/sf/briar/protocol/OfferReader.java b/components/net/sf/briar/protocol/OfferReader.java new file mode 100644 index 0000000000000000000000000000000000000000..459310dec1f056b9521266603794a390990c6b83 --- /dev/null +++ b/components/net/sf/briar/protocol/OfferReader.java @@ -0,0 +1,40 @@ +package net.sf.briar.protocol; + +import java.io.IOException; +import java.util.Collection; + +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.serial.Consumer; +import net.sf.briar.api.serial.ObjectReader; +import net.sf.briar.api.serial.Reader; + +import com.google.inject.Inject; + +class OfferReader implements ObjectReader<Offer> { + + private final ObjectReader<MessageId> messageIdReader; + private final OfferFactory offerFactory; + + @Inject + OfferReader(ObjectReader<MessageId> messageIdReader, + OfferFactory offerFactory) { + this.messageIdReader = messageIdReader; + this.offerFactory = offerFactory; + } + + public Offer readObject(Reader r) throws IOException { + // Initialise the consumer + Consumer counting = new CountingConsumer(Offer.MAX_SIZE); + // Read the data + r.addConsumer(counting); + r.readUserDefinedTag(Tags.OFFER); + r.addObjectReader(Tags.MESSAGE_ID, messageIdReader); + Collection<MessageId> messages = r.readList(MessageId.class); + r.removeObjectReader(Tags.MESSAGE_ID); + r.removeConsumer(counting); + // Build and return the offer + return offerFactory.createOffer(messages); + } +} diff --git a/components/net/sf/briar/protocol/ProtocolModule.java b/components/net/sf/briar/protocol/ProtocolModule.java index c5ea605579b52f2e1ff580b0b50423b08bf4520a..ffd8e51c9806025ccf6ce8bffb9abfe8813916ff 100644 --- a/components/net/sf/briar/protocol/ProtocolModule.java +++ b/components/net/sf/briar/protocol/ProtocolModule.java @@ -8,6 +8,7 @@ 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.protocol.MessageId; import net.sf.briar.api.serial.ObjectReader; import com.google.inject.AbstractModule; @@ -21,6 +22,7 @@ public class ProtocolModule extends AbstractModule { bind(AuthorFactory.class).to(AuthorFactoryImpl.class); bind(BatchFactory.class).to(BatchFactoryImpl.class); bind(GroupFactory.class).to(GroupFactoryImpl.class); + bind(OfferFactory.class).to(OfferFactoryImpl.class); bind(SubscriptionFactory.class).to(SubscriptionFactoryImpl.class); bind(TransportFactory.class).to(TransportFactoryImpl.class); bind(MessageEncoder.class).to(MessageEncoderImpl.class); @@ -31,6 +33,11 @@ public class ProtocolModule extends AbstractModule { return new BatchIdReader(); } + @Provides + ObjectReader<MessageId> getMessageIdReader() { + return new MessageIdReader(); + } + @Provides ObjectReader<Group> getGroupReader(CryptoComponent crypto, GroupFactory groupFactory) { @@ -45,8 +52,10 @@ public class ProtocolModule extends AbstractModule { @Provides ObjectReader<Message> getMessageReader(CryptoComponent crypto, + ObjectReader<MessageId> messageIdReader, ObjectReader<Group> groupReader, ObjectReader<Author> authorReader) { - return new MessageReader(crypto, groupReader, authorReader); + return new MessageReader(crypto, messageIdReader, groupReader, + authorReader); } } diff --git a/components/net/sf/briar/protocol/SubscriptionReader.java b/components/net/sf/briar/protocol/SubscriptionReader.java index 88a693b26a7a95284109eb3f9ade39c94b608a8e..b3c68b9b632f5e017e00905b39f6d4d3223324b4 100644 --- a/components/net/sf/briar/protocol/SubscriptionReader.java +++ b/components/net/sf/briar/protocol/SubscriptionReader.java @@ -6,6 +6,7 @@ import java.util.Collection; import net.sf.briar.api.protocol.Group; import net.sf.briar.api.protocol.Subscriptions; import net.sf.briar.api.protocol.Tags; +import net.sf.briar.api.serial.Consumer; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; @@ -25,8 +26,7 @@ class SubscriptionReader implements ObjectReader<Subscriptions> { public Subscriptions readObject(Reader r) throws IOException { // Initialise the consumer - CountingConsumer counting = - new CountingConsumer(Subscriptions.MAX_SIZE); + Consumer counting = new CountingConsumer(Subscriptions.MAX_SIZE); // Read the data r.addConsumer(counting); r.readUserDefinedTag(Tags.SUBSCRIPTIONS); diff --git a/components/net/sf/briar/protocol/TransportReader.java b/components/net/sf/briar/protocol/TransportReader.java index 41d5f21f6f10ed42216d79bdee6b1dbc0285f992..bec0dd0f6a7ca9ff29d781d20e610b1e2385a5a7 100644 --- a/components/net/sf/briar/protocol/TransportReader.java +++ b/components/net/sf/briar/protocol/TransportReader.java @@ -5,6 +5,7 @@ import java.util.Map; import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.protocol.Transports; +import net.sf.briar.api.serial.Consumer; import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.Reader; @@ -21,7 +22,7 @@ class TransportReader implements ObjectReader<Transports> { public Transports readObject(Reader r) throws IOException { // Initialise the consumer - CountingConsumer counting = new CountingConsumer(Transports.MAX_SIZE); + Consumer counting = new CountingConsumer(Transports.MAX_SIZE); // Read the data r.addConsumer(counting); r.readUserDefinedTag(Tags.TRANSPORTS); diff --git a/test/net/sf/briar/protocol/FileReadWriteTest.java b/test/net/sf/briar/protocol/FileReadWriteTest.java index 695008fa5b3e9b7d15cde8a31facc7d693f19d33..9b77922d90458ee1c02918f204f7d43e73ef4a08 100644 --- a/test/net/sf/briar/protocol/FileReadWriteTest.java +++ b/test/net/sf/briar/protocol/FileReadWriteTest.java @@ -23,12 +23,14 @@ 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.protocol.MessageId; +import net.sf.briar.api.protocol.Offer; import net.sf.briar.api.protocol.Subscriptions; import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.protocol.Transports; import net.sf.briar.api.protocol.UniqueId; 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.SubscriptionWriter; import net.sf.briar.api.protocol.writers.TransportWriter; @@ -58,6 +60,7 @@ public class FileReadWriteTest extends TestCase { private final CryptoComponent crypto; private final AckReader ackReader; private final BatchReader batchReader; + private final OfferReader offerReader; private final SubscriptionReader subscriptionReader; private final TransportReader transportReader; private final Author author; @@ -78,6 +81,7 @@ public class FileReadWriteTest extends TestCase { UniqueId.LENGTH); ackReader = i.getInstance(AckReader.class); batchReader = i.getInstance(BatchReader.class); + offerReader = i.getInstance(OfferReader.class); subscriptionReader = i.getInstance(SubscriptionReader.class); transportReader = i.getInstance(TransportReader.class); // Create two groups: one restricted, one unrestricted @@ -124,6 +128,13 @@ public class FileReadWriteTest extends TestCase { assertTrue(b.writeMessage(message3.getBytes())); b.finish(); + OfferWriter o = packetWriterFactory.createOfferWriter(out); + assertTrue(o.writeMessageId(message.getId())); + assertTrue(o.writeMessageId(message1.getId())); + assertTrue(o.writeMessageId(message2.getId())); + assertTrue(o.writeMessageId(message3.getId())); + o.finish(); + SubscriptionWriter s = packetWriterFactory.createSubscriptionWriter(out); Collection<Group> subs = new ArrayList<Group>(); @@ -148,6 +159,7 @@ public class FileReadWriteTest extends TestCase { Reader reader = readerFactory.createReader(in); reader.addObjectReader(Tags.ACK, ackReader); reader.addObjectReader(Tags.BATCH, batchReader); + reader.addObjectReader(Tags.OFFER, offerReader); reader.addObjectReader(Tags.SUBSCRIPTIONS, subscriptionReader); reader.addObjectReader(Tags.TRANSPORTS, transportReader); @@ -166,16 +178,27 @@ public class FileReadWriteTest extends TestCase { checkMessageEquality(message1, i.next()); checkMessageEquality(message2, i.next()); checkMessageEquality(message3, i.next()); - + + // Read the offer + assertTrue(reader.hasUserDefined(Tags.OFFER)); + Offer o = reader.readUserDefined(Tags.OFFER, Offer.class); + Collection<MessageId> ids = o.getMessages(); + assertEquals(4, ids.size()); + Iterator<MessageId> i1 = ids.iterator(); + assertEquals(message.getId(), i1.next()); + assertEquals(message1.getId(), i1.next()); + assertEquals(message2.getId(), i1.next()); + assertEquals(message3.getId(), i1.next()); + // Read the subscriptions update assertTrue(reader.hasUserDefined(Tags.SUBSCRIPTIONS)); Subscriptions s = reader.readUserDefined(Tags.SUBSCRIPTIONS, Subscriptions.class); Collection<Group> subs = s.getSubscriptions(); assertEquals(2, subs.size()); - Iterator<Group> i1 = subs.iterator(); - checkGroupEquality(group, i1.next()); - checkGroupEquality(group1, i1.next()); + Iterator<Group> i2 = subs.iterator(); + checkGroupEquality(group, i2.next()); + checkGroupEquality(group1, i2.next()); assertTrue(s.getTimestamp() > start); assertTrue(s.getTimestamp() <= System.currentTimeMillis());