A very minimal no_std Consistent Overhead Byte Stuffing library written in Rust. The COBS algorithm, and thus also this crate, provides an encoding for arbitrary data which removes any occurrence of a specific marker byte. This is mostly useful when we are transferring arbitrary data which is terminated with a null byte, and therefore we don't want our arbitrary data buffer to contain any null bytes. In fact, this crate will automatically append the marker byte at the end of any encoded buffer.
Take a look at the documentation.
The cobs-rs crate only provides two specific functions. Namely, the
stuff
and the
unstuff
function,
which encode and decode respectively. This, together with the fact that the
crate doesn't use the std
, makes the crate
perfect for embedded hardware. However, it can also be used outside of embedded
systems.
Both the encode(stuff
)
and decode(unstuff
)
functions, use const
generics. This
may make usage a bit counter-intuitive for people unfamiliar with this feature
at first.
Something to take into account here is that the COBS algorithm will at most
add 2 + (size of input buffer / 256)
(with integer division) bytes to the
encoded buffer in size compared to input buffer. This fact allows us to always
reserve enough space for the output buffer.
Let us have a look at a small example of how to encode some data using the
stuff
function.
let data: [u8; 254] = [
// ...snip
];
// Our input buffer is 254 bytes long.
// Thus, we need to reserve 2 + (254 / 256) = 2 extra bytes
// for the encoded buffer.
let encoded: [u8; 256] = cobs_rs::stuff(data, 0x00);
// We can also encode much larger buffers
let a_lot_of_data: [u8; 1337] = [
// ...snip
];
// Our input buffer is 1337 bytes long.
// Thus, we need to reserve 2 + (1337 / 256) = 7 extra bytes
// for the encoded buffer.
let a_lot_of_output: [u8; 1344] = cobs_rs::stuff(a_lot_of_data, 0x00);
Note: The output buffer type specifications are always necessary. The type specifications for the input data isn't necessary most of the time.
Now, let us look at an example of how to decode data using the
unstuff
function.
It is generally a good idea to reserve size of encoded buffer - 2
bytes for
the decoded buffer. With this rule, we will always have enough space for the
encoded buffer. Next to the decoded buffer, the
unstuff
function will
also return the actual filled size of the buffer.
// We are given some encoded data buffer
let encoded_data: [u8; 256] = [
//... snip
];
// We reserve 256 - 2 = 254 bytes for the decoded buffer.
let (decoded_data: [u8; 254], decoded_data_length) =
cobs_rs::unstuff(encoded_data, 0x00);
// We can also decode bigger buffers
let a_lot_of_encoded_data: [u8; 1344] = [
//... snip
];
// We reserve 1344 - 2 = 1342 bytes for the decoded buffer.
let (a_lot_of_decoded_data: [u8; 1342], a_lot_of_decoded_data_length) =
cobs_rs::unstuff(encoded_data, 0x00);
Note: The decoded buffer type specifications are always necessary. The type specifications for the encoded data isn't necessary most of the time.
Licensed under a MIT license.