readDelimited function

Future<Uint8List> readDelimited(
  1. P2PStream stream
)

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));
}