readDelimited function
Reads a delimited message from the stream
Implementation
Future<Uint8List> readDelimited(P2PStream<dynamic> stream) async {
// Read the first byte to determine if we need to read more for the varint
final firstByte = await stream.read(1);
if (firstByte.isEmpty) {
throw FormatException('Unexpected end of stream');
}
// Determine how many more bytes we need to read for the varint
int bytesToRead = 0;
if (firstByte[0] >= 0x80) {
// We need to read more bytes
bytesToRead = 1;
int b = firstByte[0];
while (b >= 0x80 && bytesToRead < 9) {
b >>= 7;
bytesToRead++;
}
if (bytesToRead >= 9) {
throw FormatException('Varint too long');
}
}
// Read the rest of the varint bytes if needed
Uint8List varintBytes;
if (bytesToRead > 0) {
final restOfVarint = await stream.read(bytesToRead - 1);
varintBytes = Uint8List(bytesToRead);
varintBytes[0] = firstByte[0];
varintBytes.setRange(1, bytesToRead, restOfVarint);
} else {
varintBytes = firstByte;
}
// Decode the varint to get the message length
final (length, _) = decodeVarint(varintBytes);
if (length > 1024) {
throw MessageTooLargeException();
}
// Read the message
final message = await stream.read(length);
if (message.length != length) {
throw FormatException('Unexpected end of stream');
}
// Check for trailing newline
if (message.isEmpty || message[length - 1] != 10) { // '\n'
throw FormatException('Message did not have trailing newline');
}
// Return the message without the trailing newline
return Uint8List.fromList(message.sublist(0, length - 1));
}