Search documentation of Plushie

# Plushie.Transport.Framing (Plushie v0.7.2)

Copy Markdown View Source

Frame encoding and decoding for the plushie wire protocol.

Transports that deliver raw byte streams (SSH channels, raw sockets) need to frame protocol messages. This module provides the framing logic for both MessagePack (4-byte length prefix) and JSON (newline delimiter) modes.

Transports with built-in framing (e.g., `:gen_tcp` with `{:packet, 4}`, Erlang Ports with `{:packet, 4}`) don't need this module.

## MessagePack framing

Each message is prefixed with a 4-byte big-endian unsigned integer indicating the payload size:

    <<size::32-big, payload::binary-size(size)>>

## JSON framing

Each message is terminated by a newline character (`\n`). Messages must not contain embedded newlines.

## Size cap

Both framings reject messages larger than `Elixir.Plushie.Transport.Framing.max_message_size/0` (64 MiB) by raising `Plushie.Transport.BufferOverflowError`. Oversized frames are a protocol violation: silently dropping them risks desync, and the payload cannot legitimately exceed the cap.

## Summary

### Functions

decode_lines(buffer)

Decode complete lines from accumulated bytes (JSON mode).

decode_packets(buffer)

Decode complete frames from accumulated bytes (MessagePack mode).

encode_line(data)

Encode a protocol message with a newline terminator (JSON mode).

encode_packet(data)

Encode a protocol message with a 4-byte length prefix (MessagePack mode).

max_message_size()

The per-message size cap in bytes.

## Functions

# decode_lines(buffer)

    @spec decode_lines(buffer :: binary()) :: {[binary()], binary()}

Decode complete lines from accumulated bytes (JSON mode).

Returns `{complete_lines, remaining_buffer}`.

Raises `Plushie.Transport.BufferOverflowError` when a completed line exceeds the 64 MiB cap, or when the partial tail has already grown past the cap without a newline.

# decode_packets(buffer)

    @spec decode_packets(buffer :: binary()) :: {[binary()], binary()}

Decode complete frames from accumulated bytes (MessagePack mode).

Returns `{complete_messages, remaining_buffer}` where `complete_messages` is a list of binaries (each a complete protocol message) and `remaining_buffer` is leftover bytes waiting for more data.

Raises `Plushie.Transport.BufferOverflowError` when a length prefix declares a frame larger than the 64 MiB cap.

## Examples

    iex> data = <<0, 0, 0, 3, "abc", 0, 0, 0, 2, "de">>
    iex> {messages, _buffer} = Plushie.Transport.Framing.decode_packets(data)
    iex> messages
    ["abc", "de"]

    iex> partial = <<0, 0, 0, 5, "he">>
    iex> {messages, buffer} = Plushie.Transport.Framing.decode_packets(partial)
    iex> {messages, buffer}
    {[], <<0, 0, 0, 5, "he">>}

# encode_line(data)

    @spec encode_line(data :: iodata()) :: iodata()

Encode a protocol message with a newline terminator (JSON mode).

Raises `Plushie.Transport.BufferOverflowError` when the encoded line exceeds the 64 MiB cap.

# encode_packet(data)

    @spec encode_packet(data :: iodata()) :: iodata()

Encode a protocol message with a 4-byte length prefix (MessagePack mode).

Returns iodata that can be written to the transport.

Raises `Plushie.Transport.BufferOverflowError` when the payload exceeds the 64 MiB cap.

# max_message_size()

    @spec max_message_size() :: pos_integer()

The per-message size cap in bytes.

Matches the renderer's cap so both ends reject the same threshold.