mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 22:59:54 +01:00
Factored out header reading and batch reading into separate classes
for easier testing.
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
package net.sf.briar.api.serial;
|
package net.sf.briar.api.serial;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
|
||||||
public interface ObjectReader<T> {
|
public interface ObjectReader<T> {
|
||||||
|
|
||||||
T readObject(Reader r) throws IOException;
|
T readObject(Reader r) throws IOException, GeneralSecurityException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.sf.briar.api.serial;
|
package net.sf.briar.api.serial;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -42,16 +43,18 @@ public interface Reader {
|
|||||||
byte[] readRaw() throws IOException;
|
byte[] readRaw() throws IOException;
|
||||||
|
|
||||||
boolean hasList() throws IOException;
|
boolean hasList() throws IOException;
|
||||||
List<Object> readList() throws IOException;
|
List<Object> readList() throws IOException, GeneralSecurityException;
|
||||||
<E> List<E> readList(Class<E> e) throws IOException;
|
<E> List<E> readList(Class<E> e) throws IOException,
|
||||||
|
GeneralSecurityException;
|
||||||
boolean hasListStart() throws IOException;
|
boolean hasListStart() throws IOException;
|
||||||
void readListStart() throws IOException;
|
void readListStart() throws IOException;
|
||||||
boolean hasListEnd() throws IOException;
|
boolean hasListEnd() throws IOException;
|
||||||
void readListEnd() throws IOException;
|
void readListEnd() throws IOException;
|
||||||
|
|
||||||
boolean hasMap() throws IOException;
|
boolean hasMap() throws IOException;
|
||||||
Map<Object, Object> readMap() throws IOException;
|
Map<Object, Object> readMap() throws IOException, GeneralSecurityException;
|
||||||
<K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException;
|
<K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException,
|
||||||
|
GeneralSecurityException;
|
||||||
boolean hasMapStart() throws IOException;
|
boolean hasMapStart() throws IOException;
|
||||||
void readMapStart() throws IOException;
|
void readMapStart() throws IOException;
|
||||||
boolean hasMapEnd() throws IOException;
|
boolean hasMapEnd() throws IOException;
|
||||||
@@ -63,5 +66,6 @@ public interface Reader {
|
|||||||
boolean hasUserDefinedTag() throws IOException;
|
boolean hasUserDefinedTag() throws IOException;
|
||||||
int readUserDefinedTag() throws IOException;
|
int readUserDefinedTag() throws IOException;
|
||||||
void readUserDefinedTag(int tag) throws IOException;
|
void readUserDefinedTag(int tag) throws IOException;
|
||||||
<T> T readUserDefinedObject(int tag) throws IOException;
|
<T> T readUserDefinedObject(int tag) throws IOException,
|
||||||
|
GeneralSecurityException;
|
||||||
}
|
}
|
||||||
|
|||||||
62
components/net/sf/briar/protocol/BatchReader.java
Normal file
62
components/net/sf/briar/protocol/BatchReader.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package net.sf.briar.protocol;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.Signature;
|
||||||
|
import java.security.SignatureException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.ObjectReader;
|
||||||
|
import net.sf.briar.api.serial.Reader;
|
||||||
|
|
||||||
|
public class BatchReader implements ObjectReader<Batch> {
|
||||||
|
|
||||||
|
private final PublicKey publicKey;
|
||||||
|
private final Signature signature;
|
||||||
|
private final MessageDigest messageDigest;
|
||||||
|
private final ObjectReader<Message> messageReader;
|
||||||
|
private final BatchFactory batchFactory;
|
||||||
|
|
||||||
|
BatchReader(PublicKey publicKey, Signature signature,
|
||||||
|
MessageDigest messageDigest, ObjectReader<Message> messageReader,
|
||||||
|
BatchFactory batchFactory) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this.signature = signature;
|
||||||
|
this.messageDigest = messageDigest;
|
||||||
|
this.messageReader = messageReader;
|
||||||
|
this.batchFactory = batchFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Batch readObject(Reader reader) throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
|
// Initialise the input stream
|
||||||
|
CountingConsumer counting = new CountingConsumer(Batch.MAX_SIZE);
|
||||||
|
DigestingConsumer digesting = new DigestingConsumer(messageDigest);
|
||||||
|
messageDigest.reset();
|
||||||
|
SigningConsumer signing = new SigningConsumer(signature);
|
||||||
|
signature.initVerify(publicKey);
|
||||||
|
// Read the signed data
|
||||||
|
reader.addConsumer(counting);
|
||||||
|
reader.addConsumer(digesting);
|
||||||
|
reader.addConsumer(signing);
|
||||||
|
reader.addObjectReader(Tags.MESSAGE, messageReader);
|
||||||
|
List<Message> messages = reader.readList(Message.class);
|
||||||
|
reader.removeObjectReader(Tags.MESSAGE);
|
||||||
|
reader.removeConsumer(signing);
|
||||||
|
// Read and verify the signature
|
||||||
|
reader.readUserDefinedTag(Tags.SIGNATURE);
|
||||||
|
byte[] sig = reader.readRaw();
|
||||||
|
reader.removeConsumer(digesting);
|
||||||
|
reader.removeConsumer(counting);
|
||||||
|
if(!signature.verify(sig)) throw new SignatureException();
|
||||||
|
// Build and return the batch
|
||||||
|
BatchId id = new BatchId(messageDigest.digest());
|
||||||
|
return batchFactory.createBatch(id, messages);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,20 +2,10 @@ package net.sf.briar.protocol;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.Signature;
|
|
||||||
import java.security.SignatureException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Batch;
|
import net.sf.briar.api.protocol.Batch;
|
||||||
import net.sf.briar.api.protocol.BatchId;
|
|
||||||
import net.sf.briar.api.protocol.BundleReader;
|
import net.sf.briar.api.protocol.BundleReader;
|
||||||
import net.sf.briar.api.protocol.GroupId;
|
|
||||||
import net.sf.briar.api.protocol.Header;
|
import net.sf.briar.api.protocol.Header;
|
||||||
import net.sf.briar.api.protocol.Message;
|
|
||||||
import net.sf.briar.api.protocol.Tags;
|
import net.sf.briar.api.protocol.Tags;
|
||||||
import net.sf.briar.api.serial.FormatException;
|
import net.sf.briar.api.serial.FormatException;
|
||||||
import net.sf.briar.api.serial.ObjectReader;
|
import net.sf.briar.api.serial.ObjectReader;
|
||||||
@@ -26,102 +16,44 @@ class BundleReaderImpl implements BundleReader {
|
|||||||
private static enum State { START, FIRST_BATCH, MORE_BATCHES, END };
|
private static enum State { START, FIRST_BATCH, MORE_BATCHES, END };
|
||||||
|
|
||||||
private final Reader reader;
|
private final Reader reader;
|
||||||
private final PublicKey publicKey;
|
private final ObjectReader<Header> headerReader;
|
||||||
private final Signature signature;
|
private final ObjectReader<Batch> batchReader;
|
||||||
private final MessageDigest messageDigest;
|
|
||||||
private final ObjectReader<Message> messageReader;
|
|
||||||
private final HeaderFactory headerFactory;
|
|
||||||
private final BatchFactory batchFactory;
|
|
||||||
private State state = State.START;
|
private State state = State.START;
|
||||||
|
|
||||||
BundleReaderImpl(Reader reader, PublicKey publicKey, Signature signature,
|
BundleReaderImpl(Reader reader, ObjectReader<Header> headerReader,
|
||||||
MessageDigest messageDigest, ObjectReader<Message> messageReader,
|
ObjectReader<Batch> batchReader) {
|
||||||
HeaderFactory headerFactory, BatchFactory batchFactory) {
|
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
this.publicKey = publicKey;
|
this.headerReader = headerReader;
|
||||||
this.signature = signature;
|
this.batchReader = batchReader;
|
||||||
this.messageDigest = messageDigest;
|
|
||||||
this.messageReader = messageReader;
|
|
||||||
this.headerFactory = headerFactory;
|
|
||||||
this.batchFactory = batchFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Header getHeader() throws IOException, GeneralSecurityException {
|
public Header getHeader() throws IOException, GeneralSecurityException {
|
||||||
if(state != State.START) throw new IllegalStateException();
|
if(state != State.START) throw new IllegalStateException();
|
||||||
state = State.FIRST_BATCH;
|
reader.addObjectReader(Tags.HEADER, headerReader);
|
||||||
// Initialise the input stream
|
|
||||||
CountingConsumer counting = new CountingConsumer(Header.MAX_SIZE);
|
|
||||||
SigningConsumer signing = new SigningConsumer(signature);
|
|
||||||
signature.initVerify(publicKey);
|
|
||||||
// Read the initial tag
|
|
||||||
reader.readUserDefinedTag(Tags.HEADER);
|
reader.readUserDefinedTag(Tags.HEADER);
|
||||||
// Read the signed data
|
Header h = reader.readUserDefinedObject(Tags.HEADER);
|
||||||
reader.addConsumer(counting);
|
reader.removeObjectReader(Tags.HEADER);
|
||||||
reader.addConsumer(signing);
|
state = State.FIRST_BATCH;
|
||||||
reader.addObjectReader(Tags.BATCH_ID, new BatchIdReader());
|
return h;
|
||||||
reader.addObjectReader(Tags.GROUP_ID, new GroupIdReader());
|
|
||||||
// Acks
|
|
||||||
Collection<BatchId> acks = reader.readList(BatchId.class);
|
|
||||||
// Subs
|
|
||||||
Collection<GroupId> subs = reader.readList(GroupId.class);
|
|
||||||
// Transports
|
|
||||||
reader.readUserDefinedTag(Tags.TRANSPORTS);
|
|
||||||
Map<String, String> transports =
|
|
||||||
reader.readMap(String.class, String.class);
|
|
||||||
// Timestamp
|
|
||||||
reader.readUserDefinedTag(Tags.TIMESTAMP);
|
|
||||||
long timestamp = reader.readInt64();
|
|
||||||
if(timestamp < 0L) throw new FormatException();
|
|
||||||
reader.removeObjectReader(Tags.GROUP_ID);
|
|
||||||
reader.removeObjectReader(Tags.BATCH_ID);
|
|
||||||
reader.removeConsumer(signing);
|
|
||||||
// Read and verify the signature
|
|
||||||
reader.readUserDefinedTag(Tags.SIGNATURE);
|
|
||||||
byte[] sig = reader.readRaw();
|
|
||||||
reader.removeConsumer(counting);
|
|
||||||
if(!signature.verify(sig)) throw new SignatureException();
|
|
||||||
// Build and return the header
|
|
||||||
return headerFactory.createHeader(acks, subs, transports, timestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Batch getNextBatch() throws IOException, GeneralSecurityException {
|
public Batch getNextBatch() throws IOException, GeneralSecurityException {
|
||||||
if(state == State.FIRST_BATCH) {
|
if(state == State.FIRST_BATCH) {
|
||||||
reader.readListStart();
|
reader.readListStart();
|
||||||
|
reader.addObjectReader(Tags.BATCH, batchReader);
|
||||||
state = State.MORE_BATCHES;
|
state = State.MORE_BATCHES;
|
||||||
}
|
}
|
||||||
if(state != State.MORE_BATCHES) throw new IllegalStateException();
|
if(state != State.MORE_BATCHES) throw new IllegalStateException();
|
||||||
if(reader.hasListEnd()) {
|
if(reader.hasListEnd()) {
|
||||||
|
reader.removeObjectReader(Tags.BATCH);
|
||||||
reader.readListEnd();
|
reader.readListEnd();
|
||||||
// That should be all
|
// That should be all
|
||||||
if(!reader.eof()) throw new FormatException();
|
if(!reader.eof()) throw new FormatException();
|
||||||
state = State.END;
|
state = State.END;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Initialise the input stream
|
|
||||||
CountingConsumer counting = new CountingConsumer(Batch.MAX_SIZE);
|
|
||||||
DigestingConsumer digesting = new DigestingConsumer(messageDigest);
|
|
||||||
messageDigest.reset();
|
|
||||||
SigningConsumer signing = new SigningConsumer(signature);
|
|
||||||
signature.initVerify(publicKey);
|
|
||||||
// Read the initial tag
|
|
||||||
reader.readUserDefinedTag(Tags.BATCH);
|
reader.readUserDefinedTag(Tags.BATCH);
|
||||||
// Read the signed data
|
return reader.readUserDefinedObject(Tags.BATCH);
|
||||||
reader.addConsumer(counting);
|
|
||||||
reader.addConsumer(digesting);
|
|
||||||
reader.addConsumer(signing);
|
|
||||||
reader.addObjectReader(Tags.MESSAGE, messageReader);
|
|
||||||
List<Message> messages = reader.readList(Message.class);
|
|
||||||
reader.removeObjectReader(Tags.MESSAGE);
|
|
||||||
reader.removeConsumer(signing);
|
|
||||||
// Read and verify the signature
|
|
||||||
reader.readUserDefinedTag(Tags.SIGNATURE);
|
|
||||||
byte[] sig = reader.readRaw();
|
|
||||||
reader.removeConsumer(digesting);
|
|
||||||
reader.removeConsumer(counting);
|
|
||||||
if(!signature.verify(sig)) throw new SignatureException();
|
|
||||||
// Build and return the batch
|
|
||||||
BatchId id = new BatchId(messageDigest.digest());
|
|
||||||
return batchFactory.createBatch(id, messages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finish() throws IOException {
|
public void finish() throws IOException {
|
||||||
|
|||||||
66
components/net/sf/briar/protocol/HeaderReader.java
Normal file
66
components/net/sf/briar/protocol/HeaderReader.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package net.sf.briar.protocol;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.Signature;
|
||||||
|
import java.security.SignatureException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sf.briar.api.protocol.BatchId;
|
||||||
|
import net.sf.briar.api.protocol.GroupId;
|
||||||
|
import net.sf.briar.api.protocol.Header;
|
||||||
|
import net.sf.briar.api.protocol.Tags;
|
||||||
|
import net.sf.briar.api.serial.FormatException;
|
||||||
|
import net.sf.briar.api.serial.ObjectReader;
|
||||||
|
import net.sf.briar.api.serial.Reader;
|
||||||
|
|
||||||
|
class HeaderReader implements ObjectReader<Header> {
|
||||||
|
|
||||||
|
private final PublicKey publicKey;
|
||||||
|
private final Signature signature;
|
||||||
|
private final HeaderFactory headerFactory;
|
||||||
|
|
||||||
|
HeaderReader(PublicKey publicKey, Signature signature,
|
||||||
|
HeaderFactory headerFactory) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this.signature = signature;
|
||||||
|
this.headerFactory = headerFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Header readObject(Reader reader) throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
|
// Initialise the input stream
|
||||||
|
CountingConsumer counting = new CountingConsumer(Header.MAX_SIZE);
|
||||||
|
SigningConsumer signing = new SigningConsumer(signature);
|
||||||
|
signature.initVerify(publicKey);
|
||||||
|
// Read the signed data
|
||||||
|
reader.addConsumer(counting);
|
||||||
|
reader.addConsumer(signing);
|
||||||
|
// Acks
|
||||||
|
reader.addObjectReader(Tags.BATCH_ID, new BatchIdReader());
|
||||||
|
Collection<BatchId> acks = reader.readList(BatchId.class);
|
||||||
|
reader.removeObjectReader(Tags.BATCH_ID);
|
||||||
|
// Subs
|
||||||
|
reader.addObjectReader(Tags.GROUP_ID, new GroupIdReader());
|
||||||
|
Collection<GroupId> subs = reader.readList(GroupId.class);
|
||||||
|
reader.removeObjectReader(Tags.GROUP_ID);
|
||||||
|
// Transports
|
||||||
|
reader.readUserDefinedTag(Tags.TRANSPORTS);
|
||||||
|
Map<String, String> transports =
|
||||||
|
reader.readMap(String.class, String.class);
|
||||||
|
// Timestamp
|
||||||
|
reader.readUserDefinedTag(Tags.TIMESTAMP);
|
||||||
|
long timestamp = reader.readInt64();
|
||||||
|
if(timestamp < 0L) throw new FormatException();
|
||||||
|
reader.removeConsumer(signing);
|
||||||
|
// Read and verify the signature
|
||||||
|
reader.readUserDefinedTag(Tags.SIGNATURE);
|
||||||
|
byte[] sig = reader.readRaw();
|
||||||
|
reader.removeConsumer(counting);
|
||||||
|
if(!signature.verify(sig)) throw new SignatureException();
|
||||||
|
// Build and return the header
|
||||||
|
return headerFactory.createHeader(acks, subs, transports, timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package net.sf.briar.serial;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -315,11 +316,13 @@ class ReaderImpl implements Reader {
|
|||||||
|| (next & Tag.SHORT_MASK) == Tag.SHORT_LIST;
|
|| (next & Tag.SHORT_MASK) == Tag.SHORT_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Object> readList() throws IOException {
|
public List<Object> readList() throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
return readList(Object.class);
|
return readList(Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <E> List<E> readList(Class<E> e) throws IOException {
|
public <E> List<E> readList(Class<E> e) throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
if(!hasList()) throw new FormatException();
|
if(!hasList()) throw new FormatException();
|
||||||
if(next == Tag.LIST) {
|
if(next == Tag.LIST) {
|
||||||
readNext(false);
|
readNext(false);
|
||||||
@@ -337,7 +340,8 @@ class ReaderImpl implements Reader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <E> List<E> readList(Class<E> e, int length) throws IOException {
|
private <E> List<E> readList(Class<E> e, int length) throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
assert length >= 0;
|
assert length >= 0;
|
||||||
List<E> list = new ArrayList<E>();
|
List<E> list = new ArrayList<E>();
|
||||||
for(int i = 0; i < length; i++) list.add(readObject(e));
|
for(int i = 0; i < length; i++) list.add(readObject(e));
|
||||||
@@ -356,7 +360,7 @@ class ReaderImpl implements Reader {
|
|||||||
readNext(true);
|
readNext(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object readObject() throws IOException {
|
private Object readObject() throws IOException, GeneralSecurityException {
|
||||||
if(!started) throw new IllegalStateException();
|
if(!started) throw new IllegalStateException();
|
||||||
if(hasUserDefinedTag()) {
|
if(hasUserDefinedTag()) {
|
||||||
ObjectReader<?> o = objectReaders.get(readUserDefinedTag());
|
ObjectReader<?> o = objectReaders.get(readUserDefinedTag());
|
||||||
@@ -383,7 +387,8 @@ class ReaderImpl implements Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T> T readObject(Class<T> t) throws IOException {
|
private <T> T readObject(Class<T> t) throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
try {
|
try {
|
||||||
return (T) readObject();
|
return (T) readObject();
|
||||||
} catch(ClassCastException e) {
|
} catch(ClassCastException e) {
|
||||||
@@ -417,11 +422,13 @@ class ReaderImpl implements Reader {
|
|||||||
|| (next & Tag.SHORT_MASK) == Tag.SHORT_MAP;
|
|| (next & Tag.SHORT_MASK) == Tag.SHORT_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Object, Object> readMap() throws IOException {
|
public Map<Object, Object> readMap() throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
return readMap(Object.class, Object.class);
|
return readMap(Object.class, Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException {
|
public <K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
if(!hasMap()) throw new FormatException();
|
if(!hasMap()) throw new FormatException();
|
||||||
if(next == Tag.MAP) {
|
if(next == Tag.MAP) {
|
||||||
readNext(false);
|
readNext(false);
|
||||||
@@ -440,7 +447,7 @@ class ReaderImpl implements Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private <K, V> Map<K, V> readMap(Class<K> k, Class<V> v, int size)
|
private <K, V> Map<K, V> readMap(Class<K> k, Class<V> v, int size)
|
||||||
throws IOException {
|
throws IOException, GeneralSecurityException {
|
||||||
assert size >= 0;
|
assert size >= 0;
|
||||||
Map<K, V> m = new HashMap<K, V>();
|
Map<K, V> m = new HashMap<K, V>();
|
||||||
for(int i = 0; i < size; i++) m.put(readObject(k), readObject(v));
|
for(int i = 0; i < size; i++) m.put(readObject(k), readObject(v));
|
||||||
@@ -500,7 +507,8 @@ class ReaderImpl implements Reader {
|
|||||||
if(readUserDefinedTag() != tag) throw new FormatException();
|
if(readUserDefinedTag() != tag) throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T readUserDefinedObject(int tag) throws IOException {
|
public <T> T readUserDefinedObject(int tag) throws IOException,
|
||||||
|
GeneralSecurityException {
|
||||||
ObjectReader<?> o = objectReaders.get(tag);
|
ObjectReader<?> o = objectReaders.get(tag);
|
||||||
if(o == null) throw new FormatException();
|
if(o == null) throw new FormatException();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -124,13 +124,15 @@ public class BundleReadWriteTest extends TestCase {
|
|||||||
|
|
||||||
testWriteBundle();
|
testWriteBundle();
|
||||||
|
|
||||||
MessageReader messageReader =
|
|
||||||
new MessageReader(keyParser, sig1, dig1);
|
|
||||||
FileInputStream in = new FileInputStream(bundle);
|
FileInputStream in = new FileInputStream(bundle);
|
||||||
Reader reader = rf.createReader(in);
|
Reader reader = rf.createReader(in);
|
||||||
BundleReader r = new BundleReaderImpl(reader, keyPair.getPublic(), sig,
|
MessageReader messageReader = new MessageReader(keyParser, sig1, dig1);
|
||||||
dig, messageReader, new HeaderFactoryImpl(),
|
HeaderReader headerReader = new HeaderReader(keyPair.getPublic(), sig,
|
||||||
new BatchFactoryImpl());
|
new HeaderFactoryImpl());
|
||||||
|
BatchReader batchReader = new BatchReader(keyPair.getPublic(), sig, dig,
|
||||||
|
messageReader, new BatchFactoryImpl());
|
||||||
|
BundleReader r = new BundleReaderImpl(reader, headerReader,
|
||||||
|
batchReader);
|
||||||
|
|
||||||
Header h = r.getHeader();
|
Header h = r.getHeader();
|
||||||
assertEquals(acks, h.getAcks());
|
assertEquals(acks, h.getAcks());
|
||||||
@@ -164,13 +166,15 @@ public class BundleReadWriteTest extends TestCase {
|
|||||||
f.writeByte(b + 1);
|
f.writeByte(b + 1);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
MessageReader messageReader =
|
|
||||||
new MessageReader(keyParser, sig1, dig1);
|
|
||||||
FileInputStream in = new FileInputStream(bundle);
|
FileInputStream in = new FileInputStream(bundle);
|
||||||
Reader reader = rf.createReader(in);
|
Reader reader = rf.createReader(in);
|
||||||
BundleReader r = new BundleReaderImpl(reader, keyPair.getPublic(), sig,
|
MessageReader messageReader = new MessageReader(keyParser, sig1, dig1);
|
||||||
dig, messageReader, new HeaderFactoryImpl(),
|
HeaderReader headerReader = new HeaderReader(keyPair.getPublic(), sig,
|
||||||
new BatchFactoryImpl());
|
new HeaderFactoryImpl());
|
||||||
|
BatchReader batchReader = new BatchReader(keyPair.getPublic(), sig, dig,
|
||||||
|
messageReader, new BatchFactoryImpl());
|
||||||
|
BundleReader r = new BundleReaderImpl(reader, headerReader,
|
||||||
|
batchReader);
|
||||||
|
|
||||||
Header h = r.getHeader();
|
Header h = r.getHeader();
|
||||||
assertEquals(acks, h.getAcks());
|
assertEquals(acks, h.getAcks());
|
||||||
|
|||||||
5
test/net/sf/briar/protocol/BundleReaderImplTest.java
Normal file
5
test/net/sf/briar/protocol/BundleReaderImplTest.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package net.sf.briar.protocol;
|
||||||
|
|
||||||
|
public class BundleReaderImplTest {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
private ReaderImpl r = null;
|
private ReaderImpl r = null;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadBoolean() throws IOException {
|
public void testReadBoolean() throws Exception {
|
||||||
setContents("FFFE");
|
setContents("FFFE");
|
||||||
assertFalse(r.readBoolean());
|
assertFalse(r.readBoolean());
|
||||||
assertTrue(r.readBoolean());
|
assertTrue(r.readBoolean());
|
||||||
@@ -30,7 +30,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadInt8() throws IOException {
|
public void testReadInt8() throws Exception {
|
||||||
setContents("FD00" + "FDFF" + "FD7F" + "FD80");
|
setContents("FD00" + "FDFF" + "FD7F" + "FD80");
|
||||||
assertEquals((byte) 0, r.readInt8());
|
assertEquals((byte) 0, r.readInt8());
|
||||||
assertEquals((byte) -1, r.readInt8());
|
assertEquals((byte) -1, r.readInt8());
|
||||||
@@ -40,7 +40,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadInt16() throws IOException {
|
public void testReadInt16() throws Exception {
|
||||||
setContents("FC0000" + "FCFFFF" + "FC7FFF" + "FC8000");
|
setContents("FC0000" + "FCFFFF" + "FC7FFF" + "FC8000");
|
||||||
assertEquals((short) 0, r.readInt16());
|
assertEquals((short) 0, r.readInt16());
|
||||||
assertEquals((short) -1, r.readInt16());
|
assertEquals((short) -1, r.readInt16());
|
||||||
@@ -50,7 +50,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadInt32() throws IOException {
|
public void testReadInt32() throws Exception {
|
||||||
setContents("FB00000000" + "FBFFFFFFFF" + "FB7FFFFFFF" + "FB80000000");
|
setContents("FB00000000" + "FBFFFFFFFF" + "FB7FFFFFFF" + "FB80000000");
|
||||||
assertEquals(0, r.readInt32());
|
assertEquals(0, r.readInt32());
|
||||||
assertEquals(-1, r.readInt32());
|
assertEquals(-1, r.readInt32());
|
||||||
@@ -60,7 +60,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadInt64() throws IOException {
|
public void testReadInt64() throws Exception {
|
||||||
setContents("FA0000000000000000" + "FAFFFFFFFFFFFFFFFF" +
|
setContents("FA0000000000000000" + "FAFFFFFFFFFFFFFFFF" +
|
||||||
"FA7FFFFFFFFFFFFFFF" + "FA8000000000000000");
|
"FA7FFFFFFFFFFFFFFF" + "FA8000000000000000");
|
||||||
assertEquals(0L, r.readInt64());
|
assertEquals(0L, r.readInt64());
|
||||||
@@ -71,7 +71,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadIntAny() throws IOException {
|
public void testReadIntAny() throws Exception {
|
||||||
setContents("00" + "7F" + "FD80" + "FDFF" + "FC0080" + "FC7FFF" +
|
setContents("00" + "7F" + "FD80" + "FDFF" + "FC0080" + "FC7FFF" +
|
||||||
"FB00008000" + "FB7FFFFFFF" + "FA0000000080000000");
|
"FB00008000" + "FB7FFFFFFF" + "FA0000000080000000");
|
||||||
assertEquals(0L, r.readIntAny());
|
assertEquals(0L, r.readIntAny());
|
||||||
@@ -87,7 +87,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadFloat32() throws IOException {
|
public void testReadFloat32() throws Exception {
|
||||||
// http://babbage.cs.qc.edu/IEEE-754/Decimal.html
|
// http://babbage.cs.qc.edu/IEEE-754/Decimal.html
|
||||||
// http://steve.hollasch.net/cgindex/coding/ieeefloat.html
|
// http://steve.hollasch.net/cgindex/coding/ieeefloat.html
|
||||||
setContents("F900000000" + "F93F800000" + "F940000000" + "F9BF800000" +
|
setContents("F900000000" + "F93F800000" + "F940000000" + "F9BF800000" +
|
||||||
@@ -104,7 +104,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadFloat64() throws IOException {
|
public void testReadFloat64() throws Exception {
|
||||||
setContents("F80000000000000000" + "F83FF0000000000000" +
|
setContents("F80000000000000000" + "F83FF0000000000000" +
|
||||||
"F84000000000000000" + "F8BFF0000000000000" +
|
"F84000000000000000" + "F8BFF0000000000000" +
|
||||||
"F88000000000000000" + "F8FFF0000000000000" +
|
"F88000000000000000" + "F8FFF0000000000000" +
|
||||||
@@ -121,7 +121,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadString() throws IOException {
|
public void testReadString() throws Exception {
|
||||||
setContents("F703666F6F" + "83666F6F" + "F700" + "80");
|
setContents("F703666F6F" + "83666F6F" + "F700" + "80");
|
||||||
assertEquals("foo", r.readString());
|
assertEquals("foo", r.readString());
|
||||||
assertEquals("foo", r.readString());
|
assertEquals("foo", r.readString());
|
||||||
@@ -131,7 +131,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadRaw() throws IOException {
|
public void testReadRaw() throws Exception {
|
||||||
setContents("F603010203" + "93010203" + "F600" + "90");
|
setContents("F603010203" + "93010203" + "F600" + "90");
|
||||||
assertTrue(Arrays.equals(new byte[] {1, 2, 3}, r.readRaw()));
|
assertTrue(Arrays.equals(new byte[] {1, 2, 3}, r.readRaw()));
|
||||||
assertTrue(Arrays.equals(new byte[] {1, 2, 3}, r.readRaw()));
|
assertTrue(Arrays.equals(new byte[] {1, 2, 3}, r.readRaw()));
|
||||||
@@ -141,7 +141,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadShortList() throws IOException {
|
public void testReadShortList() throws Exception {
|
||||||
setContents("A" + "3" + "01" + "83666F6F" + "FC0080");
|
setContents("A" + "3" + "01" + "83666F6F" + "FC0080");
|
||||||
List<Object> l = r.readList(Object.class);
|
List<Object> l = r.readList(Object.class);
|
||||||
assertNotNull(l);
|
assertNotNull(l);
|
||||||
@@ -153,7 +153,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadList() throws IOException {
|
public void testReadList() throws Exception {
|
||||||
setContents("F5" + "03" + "01" + "83666F6F" + "FC0080");
|
setContents("F5" + "03" + "01" + "83666F6F" + "FC0080");
|
||||||
List<Object> l = r.readList(Object.class);
|
List<Object> l = r.readList(Object.class);
|
||||||
assertNotNull(l);
|
assertNotNull(l);
|
||||||
@@ -165,7 +165,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadListTypeSafe() throws IOException {
|
public void testReadListTypeSafe() throws Exception {
|
||||||
setContents("A" + "3" + "01" + "02" + "03");
|
setContents("A" + "3" + "01" + "02" + "03");
|
||||||
List<Byte> l = r.readList(Byte.class);
|
List<Byte> l = r.readList(Byte.class);
|
||||||
assertNotNull(l);
|
assertNotNull(l);
|
||||||
@@ -177,7 +177,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadShortMap() throws IOException {
|
public void testReadShortMap() throws Exception {
|
||||||
setContents("B" + "2" + "83666F6F" + "7B" + "90" + "F0");
|
setContents("B" + "2" + "83666F6F" + "7B" + "90" + "F0");
|
||||||
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
||||||
assertNotNull(m);
|
assertNotNull(m);
|
||||||
@@ -190,7 +190,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadMap() throws IOException {
|
public void testReadMap() throws Exception {
|
||||||
setContents("F4" + "02" + "83666F6F" + "7B" + "90" + "F0");
|
setContents("F4" + "02" + "83666F6F" + "7B" + "90" + "F0");
|
||||||
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
||||||
assertNotNull(m);
|
assertNotNull(m);
|
||||||
@@ -203,7 +203,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadMapTypeSafe() throws IOException {
|
public void testReadMapTypeSafe() throws Exception {
|
||||||
setContents("B" + "2" + "83666F6F" + "7B" + "80" + "F0");
|
setContents("B" + "2" + "83666F6F" + "7B" + "80" + "F0");
|
||||||
Map<String, Byte> m = r.readMap(String.class, Byte.class);
|
Map<String, Byte> m = r.readMap(String.class, Byte.class);
|
||||||
assertNotNull(m);
|
assertNotNull(m);
|
||||||
@@ -215,7 +215,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDelimitedList() throws IOException {
|
public void testReadDelimitedList() throws Exception {
|
||||||
setContents("F3" + "01" + "83666F6F" + "FC0080" + "F1");
|
setContents("F3" + "01" + "83666F6F" + "FC0080" + "F1");
|
||||||
List<Object> l = r.readList(Object.class);
|
List<Object> l = r.readList(Object.class);
|
||||||
assertNotNull(l);
|
assertNotNull(l);
|
||||||
@@ -227,7 +227,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDelimitedListElements() throws IOException {
|
public void testReadDelimitedListElements() throws Exception {
|
||||||
setContents("F3" + "01" + "83666F6F" + "FC0080" + "F1");
|
setContents("F3" + "01" + "83666F6F" + "FC0080" + "F1");
|
||||||
assertTrue(r.hasListStart());
|
assertTrue(r.hasListStart());
|
||||||
r.readListStart();
|
r.readListStart();
|
||||||
@@ -243,7 +243,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDelimitedListTypeSafe() throws IOException {
|
public void testReadDelimitedListTypeSafe() throws Exception {
|
||||||
setContents("F3" + "01" + "02" + "03" + "F1");
|
setContents("F3" + "01" + "02" + "03" + "F1");
|
||||||
List<Byte> l = r.readList(Byte.class);
|
List<Byte> l = r.readList(Byte.class);
|
||||||
assertNotNull(l);
|
assertNotNull(l);
|
||||||
@@ -255,7 +255,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDelimitedMap() throws IOException {
|
public void testReadDelimitedMap() throws Exception {
|
||||||
setContents("F2" + "83666F6F" + "7B" + "90" + "F0" + "F1");
|
setContents("F2" + "83666F6F" + "7B" + "90" + "F0" + "F1");
|
||||||
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
||||||
assertNotNull(m);
|
assertNotNull(m);
|
||||||
@@ -268,7 +268,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDelimitedMapEntries() throws IOException {
|
public void testReadDelimitedMapEntries() throws Exception {
|
||||||
setContents("F2" + "83666F6F" + "7B" + "90" + "F0" + "F1");
|
setContents("F2" + "83666F6F" + "7B" + "90" + "F0" + "F1");
|
||||||
assertTrue(r.hasMapStart());
|
assertTrue(r.hasMapStart());
|
||||||
r.readMapStart();
|
r.readMapStart();
|
||||||
@@ -287,7 +287,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDelimitedMapTypeSafe() throws IOException {
|
public void testReadDelimitedMapTypeSafe() throws Exception {
|
||||||
setContents("F2" + "83666F6F" + "7B" + "80" + "F0" + "F1");
|
setContents("F2" + "83666F6F" + "7B" + "80" + "F0" + "F1");
|
||||||
Map<String, Byte> m = r.readMap(String.class, Byte.class);
|
Map<String, Byte> m = r.readMap(String.class, Byte.class);
|
||||||
assertNotNull(m);
|
assertNotNull(m);
|
||||||
@@ -300,7 +300,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void testReadNestedMapsAndLists() throws IOException {
|
public void testReadNestedMapsAndLists() throws Exception {
|
||||||
setContents("B" + "1" + "B" + "1" + "83666F6F" + "7B" +
|
setContents("B" + "1" + "B" + "1" + "83666F6F" + "7B" +
|
||||||
"A" + "1" + "01");
|
"A" + "1" + "01");
|
||||||
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
||||||
@@ -319,7 +319,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadUserDefinedTag() throws IOException {
|
public void testReadUserDefinedTag() throws Exception {
|
||||||
setContents("C0" + "DF" + "EF" + "20" + "EF" + "FB7FFFFFFF");
|
setContents("C0" + "DF" + "EF" + "20" + "EF" + "FB7FFFFFFF");
|
||||||
assertEquals(0, r.readUserDefinedTag());
|
assertEquals(0, r.readUserDefinedTag());
|
||||||
assertEquals(31, r.readUserDefinedTag());
|
assertEquals(31, r.readUserDefinedTag());
|
||||||
@@ -329,7 +329,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadUserDefinedObject() throws IOException {
|
public void testReadUserDefinedObject() throws Exception {
|
||||||
setContents("C0" + "83666F6F");
|
setContents("C0" + "83666F6F");
|
||||||
// Add an object reader for a user-defined type
|
// Add an object reader for a user-defined type
|
||||||
r.addObjectReader(0, new ObjectReader<Foo>() {
|
r.addObjectReader(0, new ObjectReader<Foo>() {
|
||||||
@@ -342,7 +342,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadListUsingObjectReader() throws IOException {
|
public void testReadListUsingObjectReader() throws Exception {
|
||||||
setContents("A" + "1" + "C0" + "83666F6F");
|
setContents("A" + "1" + "C0" + "83666F6F");
|
||||||
// Add an object reader for a user-defined type
|
// Add an object reader for a user-defined type
|
||||||
r.addObjectReader(0, new ObjectReader<Foo>() {
|
r.addObjectReader(0, new ObjectReader<Foo>() {
|
||||||
@@ -357,7 +357,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadMapUsingObjectReader() throws IOException {
|
public void testReadMapUsingObjectReader() throws Exception {
|
||||||
setContents("B" + "1" + "C0" + "83666F6F" + "C1" + "83626172");
|
setContents("B" + "1" + "C0" + "83666F6F" + "C1" + "83626172");
|
||||||
// Add object readers for two user-defined types
|
// Add object readers for two user-defined types
|
||||||
r.addObjectReader(0, new ObjectReader<Foo>() {
|
r.addObjectReader(0, new ObjectReader<Foo>() {
|
||||||
@@ -379,7 +379,7 @@ public class ReaderImplTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadEmptyInput() throws IOException {
|
public void testReadEmptyInput() throws Exception {
|
||||||
setContents("");
|
setContents("");
|
||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user