Expand description
Consistent Overhead Byte Stuffing (COBS).
COBS rewrites a payload so that it contains no 0x00 bytes, at a cost of
at most one byte per 254 bytes of input (plus one). A zero byte can then
mark frame boundaries unambiguously, which makes COBS a common choice for
serial links, USB CDC, and radio packets where a receiver must be able to
resynchronise after noise. It is the framing used by postcard.
This module only does the byte stuffing. Combine it with
Delimited on a [0x00] delimiter to cut
the stream into frames:
use wire_codec::framing::{Delimited, Framer};
use wire_codec::{cobs, WriteBuf};
// Sender: stuff the payload, then terminate it with 0x00.
let payload = [0x11, 0x00, 0x22, 0x00];
let mut wire = [0u8; 16];
let mut out = WriteBuf::new(&mut wire);
cobs::encode(&payload, &mut out).unwrap();
out.write_u8(0x00).unwrap();
let n = out.position();
assert_eq!(&wire[..n], &[0x02, 0x11, 0x02, 0x22, 0x01, 0x00]);
// Receiver: split on 0x00, then unstuff in place.
let framer = Delimited::bounded(&[0x00]).unwrap();
let frame = framer.next_frame(&wire[..n]).unwrap().unwrap();
let mut block = [0u8; 16];
let block = &mut block[..frame.payload().len()];
block.copy_from_slice(frame.payload());
let len = cobs::decode_in_place(block).unwrap();
assert_eq!(&block[..len], &payload);All functions are allocation-free and atomic: on error nothing is written to the output cursor.
Functionsยง
- decode
- Decode one COBS block (without its
0x00delimiter) fromsrcintoout. - decode_
in_ place - Decode one COBS block in place and return the decoded length.
- encode
- COBS-encode
srcintoout. The output contains no0x00bytes and does not include a trailing delimiter. - max_
encoded_ len - Upper bound on the encoded size of a
len-byte payload, excluding the trailing0x00frame delimiter:len + ceil(len / 254), and at least 1.