re_cdr 0.1.0

CDR (Common Data Representation) encoding and decoding for ROS 2 / DDS messages
Documentation
//! Output buffers for CDR serialization.

/// 4KB growth mask.
const ALIGN_4K: usize = 0xfff;

/// Byte sink used by [`crate::CdrWriter`].
pub trait CdrBuffer {
    /// Append bytes.
    fn extend_from_slice(&mut self, data: &[u8]);

    /// Append one byte.
    fn push(&mut self, byte: u8);

    /// Current byte length.
    fn len(&self) -> usize;

    /// Whether the buffer is empty.
    fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Reserve capacity for at least `additional` more bytes.
    fn reserve(&mut self, _additional: usize) {}

    /// Reserve for a target total length.
    ///
    /// Implementations may round up.
    fn reserve_4k(&mut self, needed_total: usize) {
        let current = self.len();
        if needed_total > current {
            self.reserve(needed_total - current);
        }
    }

    /// Clear the buffer for reuse.
    fn clear(&mut self);
}

impl CdrBuffer for Vec<u8> {
    #[inline(always)]
    fn extend_from_slice(&mut self, data: &[u8]) {
        Self::extend_from_slice(self, data);
    }

    #[inline(always)]
    fn push(&mut self, byte: u8) {
        Self::push(self, byte);
    }

    #[inline(always)]
    fn len(&self) -> usize {
        Self::len(self)
    }

    #[inline(always)]
    fn reserve(&mut self, additional: usize) {
        Self::reserve(self, additional);
    }

    /// Reserve with 4KB-rounded capacity.
    #[inline]
    fn reserve_4k(&mut self, needed_total: usize) {
        let current_cap = self.capacity();
        if needed_total > current_cap {
            // Round up to next 4KB boundary.
            let new_cap = (needed_total + ALIGN_4K) & !ALIGN_4K;
            self.reserve(new_cap - self.len());
        }
    }

    #[inline(always)]
    fn clear(&mut self) {
        Self::clear(self);
    }
}