mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 06:09:55 +01:00
Avoid an unnecessary copy when parsing messages.
This commit is contained in:
@@ -7,5 +7,7 @@ public interface MessageFactory {
|
|||||||
|
|
||||||
Message createMessage(GroupId g, long timestamp, byte[] body);
|
Message createMessage(GroupId g, long timestamp, byte[] body);
|
||||||
|
|
||||||
|
Message createMessage(byte[] raw);
|
||||||
|
|
||||||
Message createMessage(MessageId m, byte[] raw);
|
Message createMessage(MessageId m, byte[] raw);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class GroupFactoryImpl implements GroupFactory {
|
class GroupFactoryImpl implements GroupFactory {
|
||||||
|
|
||||||
|
private static final byte[] FORMAT_VERSION_BYTES =
|
||||||
|
new byte[] {FORMAT_VERSION};
|
||||||
|
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -31,7 +34,7 @@ class GroupFactoryImpl implements GroupFactory {
|
|||||||
public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) {
|
public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) {
|
||||||
byte[] majorVersionBytes = new byte[INT_32_BYTES];
|
byte[] majorVersionBytes = new byte[INT_32_BYTES];
|
||||||
ByteUtils.writeUint32(majorVersion, majorVersionBytes, 0);
|
ByteUtils.writeUint32(majorVersion, majorVersionBytes, 0);
|
||||||
byte[] hash = crypto.hash(LABEL, new byte[] {FORMAT_VERSION},
|
byte[] hash = crypto.hash(LABEL, FORMAT_VERSION_BYTES,
|
||||||
StringUtils.toUtf8(c.getString()), majorVersionBytes,
|
StringUtils.toUtf8(c.getString()), majorVersionBytes,
|
||||||
descriptor);
|
descriptor);
|
||||||
return new Group(new GroupId(hash), c, majorVersion, descriptor);
|
return new Group(new GroupId(hash), c, majorVersion, descriptor);
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class MessageFactoryImpl implements MessageFactory {
|
class MessageFactoryImpl implements MessageFactory {
|
||||||
|
|
||||||
|
private static final byte[] FORMAT_VERSION_BYTES =
|
||||||
|
new byte[] {FORMAT_VERSION};
|
||||||
|
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -35,14 +38,7 @@ class MessageFactoryImpl implements MessageFactory {
|
|||||||
public Message createMessage(GroupId g, long timestamp, byte[] body) {
|
public Message createMessage(GroupId g, long timestamp, byte[] body) {
|
||||||
if (body.length > MAX_MESSAGE_BODY_LENGTH)
|
if (body.length > MAX_MESSAGE_BODY_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
byte[] versionBytes = new byte[] {FORMAT_VERSION};
|
MessageId id = getMessageId(g, timestamp, body);
|
||||||
// There's only one block, so the root hash is the hash of the block
|
|
||||||
byte[] rootHash = crypto.hash(BLOCK_LABEL, versionBytes, body);
|
|
||||||
byte[] timeBytes = new byte[INT_64_BYTES];
|
|
||||||
ByteUtils.writeUint64(timestamp, timeBytes, 0);
|
|
||||||
byte[] idHash = crypto.hash(ID_LABEL, versionBytes, g.getBytes(),
|
|
||||||
timeBytes, rootHash);
|
|
||||||
MessageId id = new MessageId(idHash);
|
|
||||||
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
|
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
|
||||||
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
|
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
|
||||||
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
|
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
|
||||||
@@ -50,6 +46,32 @@ class MessageFactoryImpl implements MessageFactory {
|
|||||||
return new Message(id, g, timestamp, raw);
|
return new Message(id, g, timestamp, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MessageId getMessageId(GroupId g, long timestamp, byte[] body) {
|
||||||
|
// There's only one block, so the root hash is the hash of the block
|
||||||
|
byte[] rootHash = crypto.hash(BLOCK_LABEL, FORMAT_VERSION_BYTES, body);
|
||||||
|
byte[] timeBytes = new byte[INT_64_BYTES];
|
||||||
|
ByteUtils.writeUint64(timestamp, timeBytes, 0);
|
||||||
|
byte[] idHash = crypto.hash(ID_LABEL, FORMAT_VERSION_BYTES,
|
||||||
|
g.getBytes(), timeBytes, rootHash);
|
||||||
|
return new MessageId(idHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message createMessage(byte[] raw) {
|
||||||
|
if (raw.length < MESSAGE_HEADER_LENGTH)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
if (raw.length > MAX_MESSAGE_LENGTH)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
byte[] groupId = new byte[UniqueId.LENGTH];
|
||||||
|
System.arraycopy(raw, 0, groupId, 0, UniqueId.LENGTH);
|
||||||
|
GroupId g = new GroupId(groupId);
|
||||||
|
long timestamp = ByteUtils.readUint64(raw, UniqueId.LENGTH);
|
||||||
|
byte[] body = new byte[raw.length - MESSAGE_HEADER_LENGTH];
|
||||||
|
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
|
||||||
|
MessageId id = getMessageId(g, timestamp, body);
|
||||||
|
return new Message(id, g, timestamp, raw);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Message createMessage(MessageId m, byte[] raw) {
|
public Message createMessage(MessageId m, byte[] raw) {
|
||||||
if (raw.length < MESSAGE_HEADER_LENGTH)
|
if (raw.length < MESSAGE_HEADER_LENGTH)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.record.Record;
|
import org.briarproject.bramble.api.record.Record;
|
||||||
import org.briarproject.bramble.api.record.RecordReader;
|
import org.briarproject.bramble.api.record.RecordReader;
|
||||||
import org.briarproject.bramble.api.sync.Ack;
|
import org.briarproject.bramble.api.sync.Ack;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
@@ -126,20 +125,11 @@ class SyncRecordReaderImpl implements SyncRecordReader {
|
|||||||
assert nextRecord != null;
|
assert nextRecord != null;
|
||||||
byte[] payload = nextRecord.getPayload();
|
byte[] payload = nextRecord.getPayload();
|
||||||
if (payload.length < MESSAGE_HEADER_LENGTH) throw new FormatException();
|
if (payload.length < MESSAGE_HEADER_LENGTH) throw new FormatException();
|
||||||
// Group ID
|
// Validate timestamp
|
||||||
byte[] id = new byte[UniqueId.LENGTH];
|
|
||||||
System.arraycopy(payload, 0, id, 0, UniqueId.LENGTH);
|
|
||||||
GroupId groupId = new GroupId(id);
|
|
||||||
// Timestamp
|
|
||||||
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
|
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
|
||||||
if (timestamp < 0) throw new FormatException();
|
if (timestamp < 0) throw new FormatException();
|
||||||
// Body
|
|
||||||
byte[] body = new byte[payload.length - MESSAGE_HEADER_LENGTH];
|
|
||||||
System.arraycopy(payload, MESSAGE_HEADER_LENGTH, body, 0,
|
|
||||||
payload.length - MESSAGE_HEADER_LENGTH);
|
|
||||||
nextRecord = null;
|
nextRecord = null;
|
||||||
// TODO: Add a method that reuses the raw message
|
return messageFactory.createMessage(payload);
|
||||||
return messageFactory.createMessage(groupId, timestamp, body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user