Incremental, stateful pkt-line decoder for streaming HTTP bodies.
Exgit.PktLine.decode_stream/1 requires the entire response in a
single binary; this module accepts arbitrary chunks (as they arrive
from the network), yields complete packets per chunk, and retains
any partial trailing bytes in the decoder state for the next feed.
Used by Exgit.Transport.HTTP to feed Req.request(into: fun)
chunks into pkt-line decoding without ever materializing the full
response. With sideband-all framing on a multi-GB pack, this is
the difference between bounded memory and an OOM.
Usage
decoder = Decoder.new()
{:ok, decoder, pkts} = Decoder.feed(decoder, chunk1)
# ... handle pkts ...
{:ok, decoder, pkts} = Decoder.feed(decoder, chunk2)
# ... handle pkts ...
:ok = Decoder.finalize(decoder)
Summary
Functions
Feed a chunk of bytes into the decoder. Returns the updated decoder
and any complete packets that became decodable from buffer ++ chunk.
Assert the decoder has consumed all input cleanly. Returns
{:error, {:truncated, n}} if n bytes of an incomplete pkt-line
remain in the buffer.
Types
@type t() :: %Exgit.PktLine.Decoder{buffer: binary()}
Functions
@spec feed(t(), binary()) :: {:ok, t(), [Exgit.PktLine.packet()]} | Exgit.PktLine.decode_error()
Feed a chunk of bytes into the decoder. Returns the updated decoder
and any complete packets that became decodable from buffer ++ chunk.
Returns {:error, {:malformed_pkt_line, hex}} on malformed framing
(a length-prefix that is not valid hex or claims a length below the
4-byte header).
@spec finalize(t()) :: :ok | {:error, {:truncated, non_neg_integer()}}
Assert the decoder has consumed all input cleanly. Returns
{:error, {:truncated, n}} if n bytes of an incomplete pkt-line
remain in the buffer.
@spec new() :: t()