Expose serialisation overhead without breaking encapsulation.

This commit is contained in:
akwizgran
2011-09-21 13:16:58 +01:00
parent 95c3fb4fed
commit 3e60233ae0
13 changed files with 130 additions and 83 deletions

View File

@@ -3,46 +3,53 @@ package net.sf.briar.protocol.writers;
import java.io.IOException;
import java.io.OutputStream;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Types;
import net.sf.briar.api.protocol.writers.AckWriter;
import net.sf.briar.api.serial.SerialComponent;
import net.sf.briar.api.serial.Writer;
import net.sf.briar.api.serial.WriterFactory;
class AckWriterImpl implements AckWriter {
private final OutputStream out;
private final SerialComponent serial;
private final Writer w;
private boolean started = false;
private int idsWritten = 0;
private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
AckWriterImpl(OutputStream out, WriterFactory writerFactory) {
AckWriterImpl(OutputStream out, SerialComponent serial,
WriterFactory writerFactory) {
this.out = out;
this.serial = serial;
w = writerFactory.createWriter(out);
}
public boolean writeBatchId(BatchId b) throws IOException {
if(!started) {
w.writeUserDefinedTag(Types.ACK);
w.writeListStart();
started = true;
}
if(idsWritten >= Ack.MAX_IDS_PER_ACK) return false;
if(!started) start();
int length = serial.getSerialisedUniqueIdLength(Types.BATCH_ID);
if(capacity < length + serial.getSerialisedListEndLength())
return false;
b.writeTo(w);
idsWritten++;
capacity -= length;
return true;
}
public void finish() throws IOException {
if(!started) {
w.writeUserDefinedTag(Types.ACK);
w.writeListStart();
started = true;
}
if(!started) start();
w.writeListEnd();
out.flush();
capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
started = false;
}
private void start() throws IOException {
w.writeUserDefinedTag(Types.ACK);
capacity -= serial.getSerialisedUserDefinedIdLength(Types.ACK);
w.writeListStart();
capacity -= serial.getSerialisedListStartLength();
started = true;
}
}

View File

@@ -9,50 +9,53 @@ import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Types;
import net.sf.briar.api.protocol.writers.BatchWriter;
import net.sf.briar.api.serial.SerialComponent;
import net.sf.briar.api.serial.Writer;
import net.sf.briar.api.serial.WriterFactory;
class BatchWriterImpl implements BatchWriter {
private final DigestOutputStream out;
private final SerialComponent serial;
private final Writer w;
private final MessageDigest messageDigest;
private boolean started = false;
private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
BatchWriterImpl(OutputStream out, WriterFactory writerFactory,
MessageDigest messageDigest) {
BatchWriterImpl(OutputStream out, SerialComponent serial,
WriterFactory writerFactory, MessageDigest messageDigest) {
this.out = new DigestOutputStream(out, messageDigest);
this.serial = serial;
w = writerFactory.createWriter(this.out);
this.messageDigest = messageDigest;
}
public boolean writeMessage(byte[] message) throws IOException {
if(!started) {
messageDigest.reset();
w.writeUserDefinedTag(Types.BATCH);
w.writeListStart();
started = true;
}
// Allow one byte for the list end tag
int capacity = ProtocolConstants.MAX_PACKET_LENGTH
- (int) w.getBytesWritten() - 1;
if(capacity < message.length) return false;
// Bypass the writer and write each raw message directly
if(!started) start();
if(capacity < message.length + serial.getSerialisedListEndLength())
return false;
// Bypass the writer and write the raw message directly
out.write(message);
capacity -= message.length;
return true;
}
public BatchId finish() throws IOException {
if(!started) {
messageDigest.reset();
w.writeUserDefinedTag(Types.BATCH);
w.writeListStart();
started = true;
}
if(!started) start();
w.writeListEnd();
out.flush();
capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
started = false;
return new BatchId(messageDigest.digest());
}
private void start() throws IOException {
messageDigest.reset();
w.writeUserDefinedTag(Types.BATCH);
capacity -= serial.getSerialisedUserDefinedIdLength(Types.BATCH);
w.writeListStart();
capacity -= serial.getSerialisedListStartLength();
started = true;
}
}

View File

@@ -4,45 +4,50 @@ 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.ProtocolConstants;
import net.sf.briar.api.protocol.Types;
import net.sf.briar.api.protocol.writers.OfferWriter;
import net.sf.briar.api.serial.SerialComponent;
import net.sf.briar.api.serial.Writer;
import net.sf.briar.api.serial.WriterFactory;
class OfferWriterImpl implements OfferWriter {
private final OutputStream out;
private final SerialComponent serial;
private final Writer w;
private boolean started = false;
private int idsWritten = 0;
private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
OfferWriterImpl(OutputStream out, WriterFactory writerFactory) {
OfferWriterImpl(OutputStream out, SerialComponent serial,
WriterFactory writerFactory) {
this.out = out;
this.serial = serial;
w = writerFactory.createWriter(out);
}
public boolean writeMessageId(MessageId m) throws IOException {
if(!started) {
w.writeUserDefinedTag(Types.OFFER);
w.writeListStart();
started = true;
}
if(idsWritten >= Offer.MAX_IDS_PER_OFFER) return false;
if(!started) start();
int length = serial.getSerialisedUniqueIdLength(Types.MESSAGE_ID);
if(capacity < length + serial.getSerialisedListEndLength())
return false;
m.writeTo(w);
idsWritten++;
capacity -= length;
return true;
}
public void finish() throws IOException {
if(!started) {
w.writeUserDefinedTag(Types.OFFER);
w.writeListStart();
started = true;
}
if(!started) start();
w.writeListEnd();
out.flush();
capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME
started = false;
}
private void start() throws IOException {
w.writeUserDefinedTag(Types.OFFER);
w.writeListStart();
started = true;
}
}

View File

@@ -11,6 +11,7 @@ import net.sf.briar.api.protocol.writers.ProtocolWriterFactory;
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.SerialComponent;
import net.sf.briar.api.serial.WriterFactory;
import com.google.inject.Inject;
@@ -18,25 +19,27 @@ import com.google.inject.Inject;
class ProtocolWriterFactoryImpl implements ProtocolWriterFactory {
private final MessageDigest messageDigest;
private final SerialComponent serial;
private final WriterFactory writerFactory;
@Inject
ProtocolWriterFactoryImpl(CryptoComponent crypto,
WriterFactory writerFactory) {
SerialComponent serial, WriterFactory writerFactory) {
messageDigest = crypto.getMessageDigest();
this.serial = serial;
this.writerFactory = writerFactory;
}
public AckWriter createAckWriter(OutputStream out) {
return new AckWriterImpl(out, writerFactory);
return new AckWriterImpl(out, serial, writerFactory);
}
public BatchWriter createBatchWriter(OutputStream out) {
return new BatchWriterImpl(out, writerFactory, messageDigest);
return new BatchWriterImpl(out, serial, writerFactory, messageDigest);
}
public OfferWriter createOfferWriter(OutputStream out) {
return new OfferWriterImpl(out, writerFactory);
return new OfferWriterImpl(out, serial, writerFactory);
}
public RequestWriter createRequestWriter(OutputStream out) {