Exgit.PktLine.Decoder (exgit v0.1.0)

Copy Markdown View Source

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

t()

@type t() :: %Exgit.PktLine.Decoder{buffer: binary()}

Functions

feed(decoder, chunk)

@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).

finalize(decoder)

@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.

new()

@spec new() :: t()