Skip to main content

Module framing

Module framing 

Source
Expand description

Byte stream framing: turn arbitrary read chunks into complete frames.

The parsers follow the semantics of the Node.js @serialport/parser-* packages (their test suites are ported in this module’s tests), with these deliberate differences:

  • Time is passed in (now: Instant) instead of using timers, so a polling read loop drives timeouts with Framer::poll / Framer::deadline.
  • Frames are bytes. Node’s encoding option (readline, regex) only changes how Node renders a frame as a string; decoding is left to the caller.
  • Buffers are bounded (maxBufferSize, default 64 KiB; SLIP uses the default, byteLength and ccTalk are bounded by their frame size, ready keeps only a marker-sized tail): a stream that never completes a frame cannot grow memory forever. Delimiter, readline, regex, inter-byte timeout, packetLength and SLIP emit the full buffer as a frame; start/end drops the overlong open frame (keeping a later start marker).
  • Work per pushed byte is bounded: no parser rescans its whole buffer on every push, so a stream without delimiters fed byte by byte stays linear. regex looks back REGEX_LOOKBACK bytes for a match that started in earlier data, and rescans the whole buffer only each time it has doubled: a longer match that arrives in pieces is still found, at the latest when the buffered text has doubled (or with the next match).
  • Unknown option names are rejected (a typo would otherwise silently fall back to a default); the Node names and the aliases listed on each field are accepted.
  • ready finds its marker after a false start: Node resets its match on a mismatching byte without re-checking that byte, so "RREADY" never matches "READY".
  • packetLength scans for a multi-byte delimiter with a sliding window: Node drops the newest byte on a mismatch, so it only finds a multi-byte delimiter at stream start or right after a packet (00 ab ab ba misses 0xababba). At end of stream only a started packet is flushed (Node also flushes the partial delimiter window, byte-reversed). A packet ends once it is at least len + packetOverhead long, so a config where the header outgrows that cannot buffer forever.
  • regex keeps an incomplete UTF-8 sequence for the next chunk (Node decodes each chunk alone and turns a split character into U+FFFD). The pattern is regex_lite syntax, and capture groups are not spliced into the output the way JavaScript String.split does.
  • Empty frames are never emitted (Node streams drop empty pushes too).

Structs§

ConfigError
Invalid parser options.
SlipDecoder
SLIP decoder with Node SlipDecoder semantics.
SlipOptions
SLIP framing bytes (RFC 1055 defaults; start/esc_start optional).

Enums§

ByteSeq
Bytes given as a UTF-8 string or as an array of byte values.
FramerConfig
Parser selection, as sent from JavaScript ({ type: "readline", … }).
OneOrMany
A number or a list of numbers (Node accepts both for delimiter).

Constants§

DEFAULT_MAX_BUFFER
Default cap on buffered, not yet framed bytes.
REGEX_LOOKBACK
How far back (in bytes) the regex framer re-scans old text on every push for a match that may end in newly pushed data.

Traits§

Framer
A stateful framer fed with read chunks.

Functions§

slip_encode
SLIP-encode one packet. bluetooth_quirk adds a leading END and skips empty packets.