pub struct BitBuf { /* private fields */ }Expand description
A push/pull, bit-aware decode buffer for incremental framing.
Feed bytes with push as they arrive — from a socket, a channel, a callback,
anything that delivers bytes — and take whole messages off the front with pull,
which returns Ok(None) when it needs more bytes (push more and call again).
Unlike a byte cursor (bytes::BytesMut::advance), BitBuf tracks a bit position, so a
stream of messages that don’t end on byte boundaries (bit-packed frames) reassembles cleanly:
pull advances past the consumed whole bytes and retains any partial trailing byte for the
next message. It’s the pushable, in-memory counterpart to BufSource (which pulls from a
Read). no_std-compatible (alloc only).
Reclaim is deferred and in place. pull doesn’t drain consumed bytes — the next
push/try_push reclaims them in place (one memmove, only when
it avoids a reallocation), so a steady push/pull loop reuses the same allocation without
per-message churn. For a guaranteed-fixed footprint (real-time / no_std), construct a
bounded buffer: it allocates once, try_push refuses bytes
past the cap instead of growing, and grow is the only thing that reallocates.
BitBuf is also a SeekSource, so it reads through the same decode
entry points as every other cursor: Type::decode(&mut bitbuf) advances its cursor (then call
compact to reclaim). For streaming, prefer pull — it bakes
the message’s own LAYOUT (so little/lsb messages are always correct),
decodes and reclaims, and reports “need more bytes” as Ok(None). The bare Source path
instead uses the buffer’s own with_layout order (default msb/big).
use bnb::{bin, BitBuf};
#[bin(big)]
#[derive(Debug, PartialEq, Eq)]
struct Ping { seq: u16 }
let mut bb = BitBuf::new();
bb.push(&[0x00]); // only half of the first message
assert_eq!(bb.pull::<Ping>().unwrap(), None); // not a whole message yet
bb.push(&[0x01, 0x00, 0x02]); // rest of msg 1 + all of msg 2
assert_eq!(bb.pull::<Ping>().unwrap(), Some(Ping { seq: 1 }));
assert_eq!(bb.pull::<Ping>().unwrap(), Some(Ping { seq: 2 }));
assert_eq!(bb.pull::<Ping>().unwrap(), None); // drainedImplementations§
Source§impl BitBuf
impl BitBuf
Sourcepub fn with_capacity(cap: usize) -> Self
pub fn with_capacity(cap: usize) -> Self
Sourcepub fn with_layout(self, layout: Layout) -> Self
pub fn with_layout(self, layout: Layout) -> Self
Sourcepub fn capacity(&self) -> Option<usize>
pub fn capacity(&self) -> Option<usize>
The buffer’s hard capacity in bytes for a bounded buffer, or None if
it auto-grows.
Sourcepub fn try_push(&mut self, bytes: &[u8]) -> Result<(), CapacityError>
pub fn try_push(&mut self, bytes: &[u8]) -> Result<(), CapacityError>
Append bytes without reallocating, reclaiming consumed bytes in place to make room.
§Errors
CapacityError if the bytes don’t fit a bounded buffer’s capacity
(the live bytes plus the new bytes exceed cap). On an unbounded buffer it always
succeeds (growing if needed), so prefer push there.
Sourcepub fn grow(&mut self, additional: usize)
pub fn grow(&mut self, additional: usize)
Grow a bounded buffer’s capacity by additional bytes (raising the cap
and reserving the space — the one operation that reallocates a bounded buffer). On an
unbounded buffer it just reserves.
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Drop all buffered bytes and reset the cursor (keeps the allocation and any bound).
Sourcepub fn pull<T: BitDecode + BitEncode>(&mut self) -> Result<Option<T>, BitError>
pub fn pull<T: BitDecode + BitEncode>(&mut self) -> Result<Option<T>, BitError>
Decode the next complete message off the front, advancing past the bytes it consumed.
Returns Ok(None) when the buffer doesn’t yet hold a whole message — push more bytes and
call again; the cursor is left untouched, so the retry is free. A malformed message is an
Err. The byte/bit order is taken from T’s LAYOUT, so it decodes
little/lsb messages correctly regardless of with_layout.
Consumed bytes are not drained here — they are reclaimed in place by the next
push/try_push (or an explicit compact),
so a steady push/pull loop reuses the same allocation without per-message memmoves.
§Errors
A codec BitError for a malformed message.
Trait Implementations§
impl SeekSource for BitBuf
Source§impl Source for BitBuf
impl Source for BitBuf
Source§fn read_bits(&mut self, n: u32) -> Result<u128, BitError>
fn read_bits(&mut self, n: u32) -> Result<u128, BitError>
n (<= 128) bits into the low bits of a u128, in the source’s
bit order (MSB-first by default). Read moreSource§fn byte_order(&self) -> ByteOrder
fn byte_order(&self) -> ByteOrder
Source§fn bit_order(&self) -> BitOrder
fn bit_order(&self) -> BitOrder
byte_order to decide whether a byte-multiple value needs its
bytes swapped — each bit order has a natural byte layout (big-endian under MSB,
little-endian under LSB), and only the opposite declaration swaps.Source§fn seek_to_bit(&mut self, pos: usize) -> Result<(), BitError>
fn seek_to_bit(&mut self, pos: usize) -> Result<(), BitError>
pos. The default — for a forward-only
source — fails with ErrorKind::NotSeekable; seekable sources (the slice
BitReader) override it. A SeekSource guarantees this works. Read moreSource§fn read_bytes(&mut self, n: usize) -> Result<Vec<u8>, BitError>
fn read_bytes(&mut self, n: usize) -> Result<Vec<u8>, BitError>
n bytes into a fresh Vec (at any bit offset — the bytes need not be
aligned). The bulk form of the per-byte read::<u8>() loop, for blob/payload
reads in custom codecs and container formats. Read moreSource§fn read_into(&mut self, buf: &mut [u8]) -> Result<(), BitError>
fn read_into(&mut self, buf: &mut [u8]) -> Result<(), BitError>
buf with bytes from the source — the no-alloc dual of
read_bytes, for fixed scratch buffers and tight
no_std paths. Read moreSource§fn as_read(&mut self) -> SourceReader<'_, Self> ⓘwhere
Self: Sized,
fn as_read(&mut self) -> SourceReader<'_, Self> ⓘwhere
Self: Sized,
std only.std::io::Read over its bytes — for handing the
cursor to std::io-based code from a #[br(parse_with = …)] (e.g. a decoder, or
a Read-based parser). Reads 8 bits per byte; see SourceReader. Only with
the std feature.