Merged small reader classes into ProtocolReaderImpl.

The structure of the reader now resembles that of the writer, which
should make it easier to spot discrepancies.
This commit is contained in:
akwizgran
2013-01-28 21:00:59 +00:00
parent 0141365963
commit d0904d8f1b
11 changed files with 136 additions and 386 deletions

View File

@@ -1,43 +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.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sf.briar.api.Bytes;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.UniqueId;
import net.sf.briar.api.serial.Consumer;
import net.sf.briar.api.serial.CountingConsumer;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class AckReader implements StructReader<Ack> {
public Ack readStruct(Reader r) throws IOException {
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(ACK);
// Read the message IDs as byte arrays
r.setMaxBytesLength(UniqueId.LENGTH);
List<Bytes> raw = r.readList(Bytes.class);
r.resetMaxBytesLength();
r.removeConsumer(counting);
if(raw.isEmpty()) throw new FormatException();
// Convert the byte arrays to message IDs
List<MessageId> acked = new ArrayList<MessageId>();
for(Bytes b : raw) {
if(b.getBytes().length != UniqueId.LENGTH)
throw new FormatException();
acked.add(new MessageId(b.getBytes()));
}
// Build and return the ack
return new Ack(Collections.unmodifiableList(acked));
}
}

View File

@@ -1,20 +0,0 @@
package net.sf.briar.protocol;
import static net.sf.briar.api.protocol.Types.EXPIRY_ACK;
import java.io.IOException;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.ExpiryAck;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class ExpiryAckReader implements StructReader<ExpiryAck> {
public ExpiryAck readStruct(Reader r) throws IOException {
r.readStructId(EXPIRY_ACK);
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new ExpiryAck(version);
}
}

View File

@@ -1,22 +0,0 @@
package net.sf.briar.protocol;
import static net.sf.briar.api.protocol.Types.EXPIRY_UPDATE;
import java.io.IOException;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.ExpiryUpdate;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class ExpiryUpdateReader implements StructReader<ExpiryUpdate> {
public ExpiryUpdate readStruct(Reader r) throws IOException {
r.readStructId(EXPIRY_UPDATE);
long expiry = r.readInt64();
if(expiry < 0L) throw new FormatException();
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new ExpiryUpdate(expiry, version);
}
}

View File

@@ -1,43 +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.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sf.briar.api.Bytes;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.UniqueId;
import net.sf.briar.api.serial.Consumer;
import net.sf.briar.api.serial.CountingConsumer;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class OfferReader implements StructReader<Offer> {
public Offer readStruct(Reader r) throws IOException {
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(OFFER);
// Read the message IDs as byte arrays
r.setMaxBytesLength(UniqueId.LENGTH);
List<Bytes> raw = r.readList(Bytes.class);
r.resetMaxBytesLength();
r.removeConsumer(counting);
if(raw.isEmpty()) throw new FormatException();
// Convert the byte arrays to message IDs
List<MessageId> messages = new ArrayList<MessageId>();
for(Bytes b : raw) {
if(b.getBytes().length != UniqueId.LENGTH)
throw new FormatException();
messages.add(new MessageId(b.getBytes()));
}
// Build and return the offer
return new Offer(Collections.unmodifiableList(messages));
}
}

View File

@@ -3,23 +3,15 @@ package net.sf.briar.protocol;
import java.util.concurrent.Executor;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.Author;
import net.sf.briar.api.protocol.AuthorFactory;
import net.sf.briar.api.protocol.ExpiryAck;
import net.sf.briar.api.protocol.ExpiryUpdate;
import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.MessageFactory;
import net.sf.briar.api.protocol.MessageVerifier;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.ProtocolReaderFactory;
import net.sf.briar.api.protocol.ProtocolWriterFactory;
import net.sf.briar.api.protocol.Request;
import net.sf.briar.api.protocol.SubscriptionAck;
import net.sf.briar.api.protocol.SubscriptionUpdate;
import net.sf.briar.api.protocol.TransportAck;
import net.sf.briar.api.protocol.TransportUpdate;
import net.sf.briar.api.protocol.UnverifiedMessage;
import net.sf.briar.api.protocol.VerificationExecutor;
import net.sf.briar.api.serial.StructReader;
@@ -70,21 +62,6 @@ public class ProtocolModule extends AbstractModule {
return new GroupReader(crypto);
}
@Provides
StructReader<Ack> getAckReader() {
return new AckReader();
}
@Provides
StructReader<ExpiryAck> getExpiryAckReader() {
return new ExpiryAckReader();
}
@Provides
StructReader<ExpiryUpdate> getExpiryUpdateReader() {
return new ExpiryUpdateReader();
}
@Provides
StructReader<UnverifiedMessage> getMessageReader(
StructReader<Group> groupReader,
@@ -92,34 +69,9 @@ public class ProtocolModule extends AbstractModule {
return new MessageReader(groupReader, authorReader);
}
@Provides
StructReader<Offer> getOfferReader() {
return new OfferReader();
}
@Provides
StructReader<Request> getRequestReader() {
return new RequestReader();
}
@Provides
StructReader<SubscriptionAck> getSubscriptionAckReader() {
return new SubscriptionAckReader();
}
@Provides
StructReader<SubscriptionUpdate> getSubscriptionUpdateReader(
StructReader<Group> groupReader) {
return new SubscriptionUpdateReader(groupReader);
}
@Provides
StructReader<TransportAck> getTransportAckReader() {
return new TransportAckReader();
}
@Provides
StructReader<TransportUpdate> getTransportUpdateReader() {
return new TransportUpdateReader();
}
}

View File

@@ -2,17 +2,9 @@ package net.sf.briar.protocol;
import java.io.InputStream;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.ExpiryAck;
import net.sf.briar.api.protocol.ExpiryUpdate;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.ProtocolReader;
import net.sf.briar.api.protocol.ProtocolReaderFactory;
import net.sf.briar.api.protocol.Request;
import net.sf.briar.api.protocol.SubscriptionAck;
import net.sf.briar.api.protocol.SubscriptionUpdate;
import net.sf.briar.api.protocol.TransportAck;
import net.sf.briar.api.protocol.TransportUpdate;
import net.sf.briar.api.protocol.UnverifiedMessage;
import net.sf.briar.api.serial.ReaderFactory;
import net.sf.briar.api.serial.StructReader;
@@ -20,52 +12,24 @@ import net.sf.briar.api.serial.StructReader;
import com.google.inject.Inject;
import com.google.inject.Provider;
// FIXME: Refactor this package to reduce boilerplate
// FIXME: See whether these providers can be got rid of
class ProtocolReaderFactoryImpl implements ProtocolReaderFactory {
private final ReaderFactory readerFactory;
private final Provider<StructReader<Ack>> ackProvider;
private final Provider<StructReader<ExpiryAck>> expiryAckProvider;
private final Provider<StructReader<ExpiryUpdate>> expiryUpdateProvider;
private final Provider<StructReader<UnverifiedMessage>> messageProvider;
private final Provider<StructReader<Offer>> offerProvider;
private final Provider<StructReader<Request>> requestProvider;
private final Provider<StructReader<SubscriptionAck>> subscriptionAckProvider;
private final Provider<StructReader<SubscriptionUpdate>> subscriptionUpdateProvider;
private final Provider<StructReader<TransportAck>> transportAckProvider;
private final Provider<StructReader<TransportUpdate>> transportUpdateProvider;
@Inject
ProtocolReaderFactoryImpl(ReaderFactory readerFactory,
Provider<StructReader<Ack>> ackProvider,
Provider<StructReader<UnverifiedMessage>> messageProvider,
Provider<StructReader<ExpiryAck>> expiryAckProvider,
Provider<StructReader<ExpiryUpdate>> expiryUpdateProvider,
Provider<StructReader<Offer>> offerProvider,
Provider<StructReader<Request>> requestProvider,
Provider<StructReader<SubscriptionAck>> subscriptionAckProvider,
Provider<StructReader<SubscriptionUpdate>> subscriptionUpdateProvider,
Provider<StructReader<TransportAck>> transportAckProvider,
Provider<StructReader<TransportUpdate>> transportUpdateProvider) {
Provider<StructReader<SubscriptionUpdate>> subscriptionUpdateProvider) {
this.readerFactory = readerFactory;
this.ackProvider = ackProvider;
this.expiryAckProvider = expiryAckProvider;
this.expiryUpdateProvider = expiryUpdateProvider;
this.messageProvider = messageProvider;
this.offerProvider = offerProvider;
this.requestProvider = requestProvider;
this.subscriptionAckProvider = subscriptionAckProvider;
this.subscriptionUpdateProvider = subscriptionUpdateProvider;
this.transportAckProvider = transportAckProvider;
this.transportUpdateProvider = transportUpdateProvider;
}
public ProtocolReader createProtocolReader(InputStream in) {
return new ProtocolReaderImpl(in, readerFactory, ackProvider.get(),
expiryAckProvider.get(), expiryUpdateProvider.get(),
messageProvider.get(), offerProvider.get(),
requestProvider.get(), subscriptionAckProvider.get(),
subscriptionUpdateProvider.get(), transportAckProvider.get(),
transportUpdateProvider.get());
return new ProtocolReaderImpl(readerFactory, messageProvider.get(),
subscriptionUpdateProvider.get(), in);
}
}

View File

@@ -1,5 +1,8 @@
package net.sf.briar.protocol;
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PROPERTIES_PER_TRANSPORT;
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PROPERTY_LENGTH;
import static net.sf.briar.api.protocol.Types.ACK;
import static net.sf.briar.api.protocol.Types.EXPIRY_ACK;
import static net.sf.briar.api.protocol.Types.EXPIRY_UPDATE;
@@ -13,132 +16,218 @@ import static net.sf.briar.api.protocol.Types.TRANSPORT_UPDATE;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import net.sf.briar.api.Bytes;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.ExpiryAck;
import net.sf.briar.api.protocol.ExpiryUpdate;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.ProtocolReader;
import net.sf.briar.api.protocol.Request;
import net.sf.briar.api.protocol.SubscriptionAck;
import net.sf.briar.api.protocol.SubscriptionUpdate;
import net.sf.briar.api.protocol.TransportAck;
import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.api.protocol.TransportUpdate;
import net.sf.briar.api.protocol.UniqueId;
import net.sf.briar.api.protocol.UnverifiedMessage;
import net.sf.briar.api.serial.Consumer;
import net.sf.briar.api.serial.CountingConsumer;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.ReaderFactory;
import net.sf.briar.api.serial.StructReader;
// This class is not thread-safe
class ProtocolReaderImpl implements ProtocolReader {
private final Reader reader;
private final StructReader<UnverifiedMessage> messageReader;
private final StructReader<SubscriptionUpdate> subscriptionUpdateReader;
private final Reader r;
ProtocolReaderImpl(InputStream in, ReaderFactory readerFactory,
StructReader<Ack> ackReader,
StructReader<ExpiryAck> expiryAckReader,
StructReader<ExpiryUpdate> expiryUpdateReader,
ProtocolReaderImpl(ReaderFactory readerFactory,
StructReader<UnverifiedMessage> messageReader,
StructReader<Offer> offerReader,
StructReader<Request> requestReader,
StructReader<SubscriptionAck> subscriptionAckReader,
StructReader<SubscriptionUpdate> subscriptionUpdateReader,
StructReader<TransportAck> transportAckReader,
StructReader<TransportUpdate> transportUpdateReader) {
reader = readerFactory.createReader(in);
reader.addStructReader(ACK, ackReader);
reader.addStructReader(MESSAGE, messageReader);
reader.addStructReader(OFFER, offerReader);
reader.addStructReader(REQUEST, requestReader);
reader.addStructReader(EXPIRY_ACK, expiryAckReader);
reader.addStructReader(EXPIRY_UPDATE, expiryUpdateReader);
reader.addStructReader(SUBSCRIPTION_ACK, subscriptionAckReader);
reader.addStructReader(SUBSCRIPTION_UPDATE, subscriptionUpdateReader);
reader.addStructReader(TRANSPORT_ACK, transportAckReader);
reader.addStructReader(TRANSPORT_UPDATE, transportUpdateReader);
InputStream in) {
this.messageReader = messageReader;
this.subscriptionUpdateReader = subscriptionUpdateReader;
r = readerFactory.createReader(in);
}
public boolean eof() throws IOException {
return reader.eof();
return r.eof();
}
public boolean hasAck() throws IOException {
return reader.hasStruct(ACK);
return r.hasStruct(ACK);
}
public Ack readAck() throws IOException {
return reader.readStruct(ACK, Ack.class);
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(ACK);
// Read the message IDs as byte arrays
r.setMaxBytesLength(UniqueId.LENGTH);
List<Bytes> raw = r.readList(Bytes.class);
r.resetMaxBytesLength();
r.removeConsumer(counting);
if(raw.isEmpty()) throw new FormatException();
// Convert the byte arrays to message IDs
List<MessageId> acked = new ArrayList<MessageId>();
for(Bytes b : raw) {
if(b.getBytes().length != UniqueId.LENGTH)
throw new FormatException();
acked.add(new MessageId(b.getBytes()));
}
// Build and return the ack
return new Ack(Collections.unmodifiableList(acked));
}
public boolean hasExpiryAck() throws IOException {
return reader.hasStruct(EXPIRY_ACK);
return r.hasStruct(EXPIRY_ACK);
}
public ExpiryAck readExpiryAck() throws IOException {
return reader.readStruct(EXPIRY_ACK, ExpiryAck.class);
r.readStructId(EXPIRY_ACK);
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new ExpiryAck(version);
}
public boolean hasExpiryUpdate() throws IOException {
return reader.hasStruct(EXPIRY_UPDATE);
return r.hasStruct(EXPIRY_UPDATE);
}
public ExpiryUpdate readExpiryUpdate() throws IOException {
return reader.readStruct(EXPIRY_UPDATE, ExpiryUpdate.class);
r.readStructId(EXPIRY_UPDATE);
long expiry = r.readInt64();
if(expiry < 0L) throw new FormatException();
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new ExpiryUpdate(expiry, version);
}
public boolean hasMessage() throws IOException {
return reader.hasStruct(MESSAGE);
return r.hasStruct(MESSAGE);
}
public UnverifiedMessage readMessage() throws IOException {
return reader.readStruct(MESSAGE, UnverifiedMessage.class);
return messageReader.readStruct(r);
}
public boolean hasOffer() throws IOException {
return reader.hasStruct(OFFER);
return r.hasStruct(OFFER);
}
public Offer readOffer() throws IOException {
return reader.readStruct(OFFER, Offer.class);
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(OFFER);
// Read the message IDs as byte arrays
r.setMaxBytesLength(UniqueId.LENGTH);
List<Bytes> raw = r.readList(Bytes.class);
r.resetMaxBytesLength();
r.removeConsumer(counting);
if(raw.isEmpty()) throw new FormatException();
// Convert the byte arrays to message IDs
List<MessageId> messages = new ArrayList<MessageId>();
for(Bytes b : raw) {
if(b.getBytes().length != UniqueId.LENGTH)
throw new FormatException();
messages.add(new MessageId(b.getBytes()));
}
// Build and return the offer
return new Offer(Collections.unmodifiableList(messages));
}
public boolean hasRequest() throws IOException {
return reader.hasStruct(REQUEST);
return r.hasStruct(REQUEST);
}
public Request readRequest() throws IOException {
return reader.readStruct(REQUEST, Request.class);
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(REQUEST);
// There may be up to 7 bits of padding at the end of the bitmap
int padding = r.readUint7();
if(padding > 7) throw new FormatException();
// Read the bitmap
byte[] bitmap = r.readBytes(MAX_PACKET_LENGTH);
r.removeConsumer(counting);
// Convert the bitmap into a BitSet
int length = bitmap.length * 8 - padding;
BitSet b = new BitSet(length);
for(int i = 0; i < bitmap.length; i++) {
for(int j = 0; j < 8 && i * 8 + j < length; j++) {
byte bit = (byte) (128 >> j);
if((bitmap[i] & bit) != 0) b.set(i * 8 + j);
}
}
return new Request(b, length);
}
public boolean hasSubscriptionAck() throws IOException {
return reader.hasStruct(SUBSCRIPTION_ACK);
return r.hasStruct(SUBSCRIPTION_ACK);
}
public SubscriptionAck readSubscriptionAck() throws IOException {
return reader.readStruct(SUBSCRIPTION_ACK, SubscriptionAck.class);
r.readStructId(SUBSCRIPTION_ACK);
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new SubscriptionAck(version);
}
public boolean hasSubscriptionUpdate() throws IOException {
return reader.hasStruct(SUBSCRIPTION_UPDATE);
return r.hasStruct(SUBSCRIPTION_UPDATE);
}
public SubscriptionUpdate readSubscriptionUpdate() throws IOException {
return reader.readStruct(SUBSCRIPTION_UPDATE,
SubscriptionUpdate.class);
return subscriptionUpdateReader.readStruct(r);
}
public boolean hasTransportAck() throws IOException {
return reader.hasStruct(TRANSPORT_ACK);
return r.hasStruct(TRANSPORT_ACK);
}
public TransportAck readTransportAck() throws IOException {
return reader.readStruct(TRANSPORT_ACK, TransportAck.class);
r.readStructId(TRANSPORT_ACK);
byte[] b = r.readBytes(UniqueId.LENGTH);
if(b.length < UniqueId.LENGTH) throw new FormatException();
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new TransportAck(new TransportId(b), version);
}
public boolean hasTransportUpdate() throws IOException {
return reader.hasStruct(TRANSPORT_UPDATE);
return r.hasStruct(TRANSPORT_UPDATE);
}
public TransportUpdate readTransportUpdate() throws IOException {
return reader.readStruct(TRANSPORT_UPDATE, TransportUpdate.class);
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(TRANSPORT_UPDATE);
// Read the transport ID
byte[] b = r.readBytes(UniqueId.LENGTH);
if(b.length < UniqueId.LENGTH) throw new FormatException();
TransportId id = new TransportId(b);
// Read the transport properties
r.setMaxStringLength(MAX_PROPERTY_LENGTH);
Map<String, String> m = r.readMap(String.class, String.class);
r.resetMaxStringLength();
if(m.size() > MAX_PROPERTIES_PER_TRANSPORT)
throw new FormatException();
// Read the version number
long version = r.readInt64();
if(version < 0L) throw new FormatException();
r.removeConsumer(counting);
// Build and return the transport update
return new TransportUpdate(id, new TransportProperties(m), version);
}
}

View File

@@ -1,39 +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.IOException;
import java.util.BitSet;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.Request;
import net.sf.briar.api.serial.Consumer;
import net.sf.briar.api.serial.CountingConsumer;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class RequestReader implements StructReader<Request> {
public Request readStruct(Reader r) throws IOException {
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(REQUEST);
// There may be up to 7 bits of padding at the end of the bitmap
int padding = r.readUint7();
if(padding > 7) throw new FormatException();
// Read the bitmap
byte[] bitmap = r.readBytes(MAX_PACKET_LENGTH);
r.removeConsumer(counting);
// Convert the bitmap into a BitSet
int length = bitmap.length * 8 - padding;
BitSet b = new BitSet(length);
for(int i = 0; i < bitmap.length; i++) {
for(int j = 0; j < 8 && i * 8 + j < length; j++) {
byte bit = (byte) (128 >> j);
if((bitmap[i] & bit) != 0) b.set(i * 8 + j);
}
}
return new Request(b, length);
}
}

View File

@@ -1,20 +0,0 @@
package net.sf.briar.protocol;
import static net.sf.briar.api.protocol.Types.SUBSCRIPTION_ACK;
import java.io.IOException;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.SubscriptionAck;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class SubscriptionAckReader implements StructReader<SubscriptionAck> {
public SubscriptionAck readStruct(Reader r) throws IOException {
r.readStructId(SUBSCRIPTION_ACK);
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new SubscriptionAck(version);
}
}

View File

@@ -1,24 +0,0 @@
package net.sf.briar.protocol;
import static net.sf.briar.api.protocol.Types.TRANSPORT_ACK;
import java.io.IOException;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.TransportAck;
import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.api.protocol.UniqueId;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class TransportAckReader implements StructReader<TransportAck> {
public TransportAck readStruct(Reader r) throws IOException {
r.readStructId(TRANSPORT_ACK);
byte[] b = r.readBytes(UniqueId.LENGTH);
if(b.length < UniqueId.LENGTH) throw new FormatException();
long version = r.readInt64();
if(version < 0L) throw new FormatException();
return new TransportAck(new TransportId(b), version);
}
}

View File

@@ -1,44 +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.ProtocolConstants.MAX_PROPERTIES_PER_TRANSPORT;
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PROPERTY_LENGTH;
import static net.sf.briar.api.protocol.Types.TRANSPORT_UPDATE;
import java.io.IOException;
import java.util.Map;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.api.protocol.TransportUpdate;
import net.sf.briar.api.protocol.UniqueId;
import net.sf.briar.api.serial.Consumer;
import net.sf.briar.api.serial.CountingConsumer;
import net.sf.briar.api.serial.Reader;
import net.sf.briar.api.serial.StructReader;
class TransportUpdateReader implements StructReader<TransportUpdate> {
public TransportUpdate readStruct(Reader r) throws IOException {
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
r.addConsumer(counting);
r.readStructId(TRANSPORT_UPDATE);
// Read the transport ID
byte[] b = r.readBytes(UniqueId.LENGTH);
if(b.length < UniqueId.LENGTH) throw new FormatException();
TransportId id = new TransportId(b);
// Read the transport properties
r.setMaxStringLength(MAX_PROPERTY_LENGTH);
Map<String, String> m = r.readMap(String.class, String.class);
r.resetMaxStringLength();
if(m.size() > MAX_PROPERTIES_PER_TRANSPORT)
throw new FormatException();
// Read the version number
long version = r.readInt64();
if(version < 0L) throw new FormatException();
r.removeConsumer(counting);
// Build and return the transport update
return new TransportUpdate(id, new TransportProperties(m), version);
}
}