Module: Plushie::Transport::Framing
- Defined in:
- lib/plushie/transport/framing.rb
Overview
Frame encoding/decoding for raw byte stream transports.
Used for IoStream adapters (SSH, TCP, WebSocket) where the
transport doesn't provide built-in message framing. Not needed
for Erlang Ports (which handle framing via {:packet, 4}) or
the Connection class (which handles framing internally).
Two modes:
- MessagePack: 4-byte big-endian length prefix
- JSON: newline-delimited (JSONL)
Both modes raise BufferOverflowError when a frame would exceed MAX_MESSAGE_SIZE.
Constant Summary collapse
- MAX_MESSAGE_SIZE =
Per-message size cap in bytes (64 MiB). Matches the renderer's cap so both ends reject the same threshold.
64 * 1024 * 1024
Class Method Summary collapse
-
.decode_lines(buffer) ⇒ Array(Array<String>, String)
Extract complete newline-delimited lines from a buffer.
-
.decode_packets(buffer) ⇒ Array(Array<String>, String)
Extract complete length-prefixed frames from a buffer.
-
.encode_line(data) ⇒ String
Encode a message as a newline-terminated line (JSONL).
-
.encode_packet(data) ⇒ String
Encode a message with a 4-byte big-endian length prefix.
Class Method Details
.decode_lines(buffer) ⇒ Array(Array<String>, String)
Extract complete newline-delimited lines from a buffer. Returns an array of complete lines and the remaining (incomplete) buffer.
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/plushie/transport/framing.rb', line 97 def decode_lines(buffer) lines = [] while (idx = buffer.index("\n")) line = buffer[0, idx] raise BufferOverflowError.new(size: line.bytesize, limit: MAX_MESSAGE_SIZE) if line.bytesize > MAX_MESSAGE_SIZE lines << line buffer = buffer[(idx + 1)..] end raise BufferOverflowError.new(size: buffer.bytesize, limit: MAX_MESSAGE_SIZE) if buffer.bytesize > MAX_MESSAGE_SIZE [lines, buffer] end |
.decode_packets(buffer) ⇒ Array(Array<String>, String)
Extract complete length-prefixed frames from a buffer. Returns an array of complete messages and the remaining (incomplete) buffer.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/plushie/transport/framing.rb', line 62 def decode_packets(buffer) buffer = buffer.b if buffer.encoding != Encoding::BINARY = [] while buffer.bytesize >= 4 length = buffer[0, 4].unpack1("N") raise BufferOverflowError.new(size: length, limit: MAX_MESSAGE_SIZE) if length > MAX_MESSAGE_SIZE break if buffer.bytesize < 4 + length << buffer[4, length] buffer = buffer[(4 + length)..] end [, buffer] end |
.encode_line(data) ⇒ String
Encode a message as a newline-terminated line (JSONL).
83 84 85 86 87 |
# File 'lib/plushie/transport/framing.rb', line 83 def encode_line(data) raise BufferOverflowError.new(size: data.bytesize, limit: MAX_MESSAGE_SIZE) if data.bytesize > MAX_MESSAGE_SIZE "#{data}\n" end |
.encode_packet(data) ⇒ String
Encode a message with a 4-byte big-endian length prefix.
47 48 49 50 51 52 |
# File 'lib/plushie/transport/framing.rb', line 47 def encode_packet(data) data = data.b if data.encoding != Encoding::BINARY raise BufferOverflowError.new(size: data.bytesize, limit: MAX_MESSAGE_SIZE) if data.bytesize > MAX_MESSAGE_SIZE [data.bytesize].pack("N") + data end |