mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-22 23:59:54 +01:00
Add generic record reader and writer.
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
package org.briarproject.bramble.api.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class Record {
|
||||||
|
|
||||||
|
public static final int RECORD_HEADER_BYTES = 4;
|
||||||
|
public static final int MAX_RECORD_PAYLOAD_BYTES = 48 * 1024; // 48 KiB
|
||||||
|
|
||||||
|
private final byte protocolVersion, recordType;
|
||||||
|
private final byte[] payload;
|
||||||
|
|
||||||
|
public Record(byte protocolVersion, byte recordType, byte[] payload) {
|
||||||
|
if (payload.length > MAX_RECORD_PAYLOAD_BYTES)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
this.protocolVersion = protocolVersion;
|
||||||
|
this.recordType = recordType;
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getProtocolVersion() {
|
||||||
|
return protocolVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRecordType() {
|
||||||
|
return recordType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getPayload() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.briarproject.bramble.api.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public interface RecordReader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and returns the next record.
|
||||||
|
*
|
||||||
|
* @throws EOFException if the end of the stream is reached without reading
|
||||||
|
* a complete record
|
||||||
|
*/
|
||||||
|
Record readRecord() throws IOException;
|
||||||
|
|
||||||
|
void close() throws IOException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.briarproject.bramble.api.record;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public interface RecordReaderFactory {
|
||||||
|
|
||||||
|
RecordReader createRecordReader(InputStream in);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.briarproject.bramble.api.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public interface RecordWriter {
|
||||||
|
|
||||||
|
void writeRecord(Record r) throws IOException;
|
||||||
|
|
||||||
|
void flush() throws IOException;
|
||||||
|
|
||||||
|
void close() throws IOException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.briarproject.bramble.api.record;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public interface RecordWriterFactory {
|
||||||
|
|
||||||
|
RecordWriter createRecordWriter(OutputStream out);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.briarproject.bramble.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.record.RecordReaderFactory;
|
||||||
|
import org.briarproject.bramble.api.record.RecordWriterFactory;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
public class RecordModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
RecordReaderFactory provideRecordReaderFactory() {
|
||||||
|
return new RecordReaderFactoryImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
RecordWriterFactory provideRecordWriterFactory() {
|
||||||
|
return new RecordWriterFactoryImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.briarproject.bramble.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.record.RecordReader;
|
||||||
|
import org.briarproject.bramble.api.record.RecordReaderFactory;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
class RecordReaderFactoryImpl implements RecordReaderFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecordReader createRecordReader(InputStream in) {
|
||||||
|
return new RecordReaderImpl(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.briarproject.bramble.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.record.Record;
|
||||||
|
import org.briarproject.bramble.api.record.RecordReader;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
||||||
|
|
||||||
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
class RecordReaderImpl implements RecordReader {
|
||||||
|
|
||||||
|
private final DataInputStream in;
|
||||||
|
|
||||||
|
RecordReaderImpl(InputStream in) {
|
||||||
|
this.in = new DataInputStream(new BufferedInputStream(in, 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Record readRecord() throws IOException {
|
||||||
|
byte protocolVersion = in.readByte();
|
||||||
|
byte recordType = in.readByte();
|
||||||
|
int payloadLength = in.readShort() & 0xFFFF; // Convert to unsigned
|
||||||
|
if (payloadLength < 0 || payloadLength > MAX_RECORD_PAYLOAD_BYTES)
|
||||||
|
throw new FormatException();
|
||||||
|
byte[] payload = new byte[payloadLength];
|
||||||
|
in.readFully(payload);
|
||||||
|
return new Record(protocolVersion, recordType, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.briarproject.bramble.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.record.RecordWriter;
|
||||||
|
import org.briarproject.bramble.api.record.RecordWriterFactory;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
class RecordWriterFactoryImpl implements RecordWriterFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecordWriter createRecordWriter(OutputStream out) {
|
||||||
|
return new RecordWriterImpl(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.briarproject.bramble.record;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.record.Record;
|
||||||
|
import org.briarproject.bramble.api.record.RecordWriter;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
class RecordWriterImpl implements RecordWriter {
|
||||||
|
|
||||||
|
private final DataOutputStream out;
|
||||||
|
|
||||||
|
RecordWriterImpl(OutputStream out) {
|
||||||
|
this.out = new DataOutputStream(new BufferedOutputStream(out, 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeRecord(Record r) throws IOException {
|
||||||
|
out.write(r.getProtocolVersion());
|
||||||
|
out.write(r.getRecordType());
|
||||||
|
byte[] payload = r.getPayload();
|
||||||
|
out.writeShort(payload.length);
|
||||||
|
out.write(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user