RpcMessageParser constructor

RpcMessageParser({
  1. LogScope? logger,
  2. int maxMessageLength = 64 * 1024 * 1024,
  3. int? maxBufferedBytes,
  4. Uint8List decompressor(
    1. Uint8List payload, {
    2. int? maxOutputBytes,
    })?,
  5. int maxMessagesPerChunk = 1024,
  6. bool emitFramed = false,
})

Creates an RpcMessageParser with the given configuration.

The decompressor, when provided, receives a maxOutputBytes hint equal to maxMessageLength so it can bound decompression and reject decompression bombs before fully materializing the output.

emitFramed makes every emitted value a complete gRPC frame instead of a bare message body. Off by default, which is what the stream layer wants: it holds a codec and takes a body. The transports that hand frames upward say so — currently http2, both directions.

It exists because the answer was otherwise unknowable to the caller. With no decompressor this parser cannot de-frame a compressed message, so it re-frames the payload and emits a FRAME; for an uncompressed one it emits a BODY. A caller receiving both had to guess which it held, and the only evidence available was the bytes — a heuristic over peer-chosen data that fired on any body whose first five bytes declared its own remaining length, silently turning a 13-byte message into an 8-byte one (B-78). Removing the guess without this flag broke every compressed message instead.

Implementation

RpcMessageParser({
  LogScope? logger,
  int maxMessageLength = 64 * 1024 * 1024,
  int? maxBufferedBytes,
  Uint8List Function(Uint8List payload, {int? maxOutputBytes})? decompressor,
  int maxMessagesPerChunk = 1024,
  bool emitFramed = false,
}) : _logger = logger ?? LogScope.noop,
     _maxMessageLength = maxMessageLength,
     _maxBufferedBytes =
         maxBufferedBytes ??
         (maxMessageLength + RpcConstants.messagePrefixSize),
     _decompressor = decompressor,
     _maxMessagesPerChunk = maxMessagesPerChunk,
     _emitFramed = emitFramed;