mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
95 lines
3.0 KiB
Java
95 lines
3.0 KiB
Java
package net.sf.briar.protocol;
|
|
|
|
import java.io.IOException;
|
|
import java.security.SignatureException;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import net.sf.briar.api.protocol.Batch;
|
|
import net.sf.briar.api.protocol.BatchBuilder;
|
|
import net.sf.briar.api.protocol.BatchId;
|
|
import net.sf.briar.api.protocol.Bundle;
|
|
import net.sf.briar.api.protocol.GroupId;
|
|
import net.sf.briar.api.protocol.Header;
|
|
import net.sf.briar.api.protocol.HeaderBuilder;
|
|
import net.sf.briar.api.protocol.Message;
|
|
import net.sf.briar.api.protocol.MessageParser;
|
|
import net.sf.briar.api.protocol.UniqueId;
|
|
import net.sf.briar.api.serial.FormatException;
|
|
import net.sf.briar.api.serial.Raw;
|
|
import net.sf.briar.api.serial.Reader;
|
|
|
|
import com.google.inject.Provider;
|
|
|
|
/** A bundle that deserialises its contents on demand using a reader. */
|
|
abstract class BundleReader implements Bundle {
|
|
|
|
private static enum State { START, FIRST_BATCH, MORE_BATCHES, END };
|
|
|
|
private final Reader r;
|
|
private final MessageParser messageParser;
|
|
private final Provider<HeaderBuilder> headerBuilderProvider;
|
|
private final Provider<BatchBuilder> batchBuilderProvider;
|
|
private State state = State.START;
|
|
|
|
BundleReader(Reader r, MessageParser messageParser,
|
|
Provider<HeaderBuilder> headerBuilderProvider,
|
|
Provider<BatchBuilder> batchBuilderProvider) {
|
|
this.r = r;
|
|
this.messageParser = messageParser;
|
|
this.headerBuilderProvider = headerBuilderProvider;
|
|
this.batchBuilderProvider = batchBuilderProvider;
|
|
}
|
|
|
|
public Header getHeader() throws IOException, SignatureException {
|
|
if(state != State.START) throw new IllegalStateException();
|
|
r.setReadLimit(Header.MAX_SIZE);
|
|
Set<BatchId> acks = new HashSet<BatchId>();
|
|
for(Raw raw : r.readList(Raw.class)) {
|
|
byte[] b = raw.getBytes();
|
|
if(b.length != UniqueId.LENGTH) throw new FormatException();
|
|
acks.add(new BatchId(b));
|
|
}
|
|
Set<GroupId> subs = new HashSet<GroupId>();
|
|
for(Raw raw : r.readList(Raw.class)) {
|
|
byte[] b = raw.getBytes();
|
|
if(b.length != UniqueId.LENGTH) throw new FormatException();
|
|
subs.add(new GroupId(b));
|
|
}
|
|
Map<String, String> transports = r.readMap(String.class, String.class);
|
|
byte[] sig = r.readRaw();
|
|
state = State.FIRST_BATCH;
|
|
HeaderBuilder h = headerBuilderProvider.get();
|
|
h.addAcks(acks);
|
|
h.addSubscriptions(subs);
|
|
h.addTransports(transports);
|
|
h.setSignature(sig);
|
|
return h.build();
|
|
}
|
|
|
|
public Batch getNextBatch() throws IOException, SignatureException {
|
|
if(state == State.FIRST_BATCH) {
|
|
r.readListStart();
|
|
state = State.MORE_BATCHES;
|
|
}
|
|
if(state != State.MORE_BATCHES) throw new IllegalStateException();
|
|
if(r.hasListEnd()) {
|
|
r.readListEnd();
|
|
state = State.END;
|
|
return null;
|
|
}
|
|
r.setReadLimit(Batch.MAX_SIZE);
|
|
List<Raw> messages = r.readList(Raw.class);
|
|
BatchBuilder b = batchBuilderProvider.get();
|
|
for(Raw r : messages) {
|
|
Message m = messageParser.parseMessage(r.getBytes());
|
|
b.addMessage(m);
|
|
}
|
|
byte[] sig = r.readRaw();
|
|
b.setSignature(sig);
|
|
return b.build();
|
|
}
|
|
}
|