pub struct Buffer { /* private fields */ }Expand description
A high-performance linear buffer with position tracking.
The buffer automatically and securely zeros its memory on drop using
the zeroize crate, which provides compiler-resistant memory clearing.
§Memory Safety
All buffer memory is automatically zeroed when the buffer is dropped, preventing sensitive data from remaining in memory.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_u32(42)?;
buf.put_bytes(b"hello")?;Implementations§
Source§impl Buffer
impl Buffer
Sourcepub fn new(size: usize) -> Self
pub fn new(size: usize) -> Self
Creates a new buffer with zeroed memory.
For large buffers (>4KB), the OS typically provides zero-filled pages efficiently via demand paging, making this nearly as fast as uninitialized allocation.
§Panics
Panics if size exceeds BUF_MAX_SIZE (1GB).
§Examples
use secbuf::Buffer;
let buf = Buffer::new(8192);
assert_eq!(buf.capacity(), 8192);
assert_eq!(buf.len(), 0);Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new buffer with pre-allocated capacity but zero length.
This is more efficient than new when you know the maximum
size but want to grow the buffer incrementally. The internal Vec will
only be zeroed for the portions actually used.
§Panics
Panics if capacity exceeds BUF_MAX_SIZE (1GB).
§Examples
use secbuf::Buffer;
let mut buf = Buffer::with_capacity(8192);
assert_eq!(buf.capacity(), 8192);
assert_eq!(buf.len(), 0);Sourcepub fn from_vec(data: Vec<u8>) -> Self
pub fn from_vec(data: Vec<u8>) -> Self
Creates a new buffer from existing data.
The buffer’s length is set to the vector’s length, and the position is set to 0.
§Examples
use secbuf::Buffer;
let data = vec![1, 2, 3, 4, 5];
let buf = Buffer::from_vec(data);
assert_eq!(buf.len(), 5);
assert_eq!(buf.pos(), 0);Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the total capacity of the buffer.
§Examples
use secbuf::Buffer;
let buf = Buffer::new(1024);
assert_eq!(buf.capacity(), 1024);Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the length of valid data in the buffer.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
assert_eq!(buf.len(), 0);
buf.put_u32(42)?;
assert_eq!(buf.len(), 4);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the buffer contains no valid data.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
assert!(buf.is_empty());
buf.put_u32(42)?;
assert!(!buf.is_empty());Sourcepub fn pos(&self) -> usize
pub fn pos(&self) -> usize
Returns the current read/write position.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
assert_eq!(buf.pos(), 0);
buf.put_u32(42)?;
assert_eq!(buf.pos(), 4);Sourcepub fn remaining(&self) -> usize
pub fn remaining(&self) -> usize
Returns the number of bytes available to read from current position.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_u32(42)?;
buf.put_u32(43)?;
buf.set_pos(0)?;
assert_eq!(buf.remaining(), 8);
buf.get_u32()?;
assert_eq!(buf.remaining(), 4);Sourcepub fn has_remaining(&self, count: usize) -> bool
pub fn has_remaining(&self, count: usize) -> bool
Checks if at least count bytes are available to read.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_u32(42)?;
buf.set_pos(0)?;
assert!(buf.has_remaining(4));
assert!(!buf.has_remaining(5));Sourcepub fn set_pos(&mut self, pos: usize) -> Result<()>
pub fn set_pos(&mut self, pos: usize) -> Result<()>
Sets the read/write position.
§Errors
Returns BufferError::PositionOutOfBounds if pos exceeds the buffer length.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_u32(42)?;
buf.set_pos(0)?;
assert_eq!(buf.get_u32()?, 42);Sourcepub fn set_len(&mut self, len: usize) -> Result<()>
pub fn set_len(&mut self, len: usize) -> Result<()>
Sets the length of valid data.
When using with_capacity, this will grow the
internal Vec if needed.
§Errors
Returns BufferError::SizeTooBig if len exceeds BUF_MAX_SIZE.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::with_capacity(1024);
buf.set_len(100)?;
assert_eq!(buf.len(), 100);Sourcepub fn incr_pos(&mut self, incr: usize) -> Result<()>
pub fn incr_pos(&mut self, incr: usize) -> Result<()>
Increments the position by incr.
§Errors
Returns BufferError::IncrementTooLarge if the increment is too large
or would exceed the buffer length.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_bytes(b"hello")?;
buf.set_pos(0)?;
buf.incr_pos(2)?;
assert_eq!(buf.pos(), 2);Sourcepub fn decr_pos(&mut self, decr: usize) -> Result<()>
pub fn decr_pos(&mut self, decr: usize) -> Result<()>
Decrements the position by decr.
§Errors
Returns BufferError::PositionOutOfBounds if decr exceeds the current position.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_u32(42)?;
buf.decr_pos(2)?;
assert_eq!(buf.pos(), 2);Sourcepub fn incr_len(&mut self, incr: usize) -> Result<()>
pub fn incr_len(&mut self, incr: usize) -> Result<()>
Increments the length by incr.
When using with_capacity, this will grow the
internal Vec if needed.
§Errors
Returns BufferError::IncrementTooLarge if the increment is too large.
Returns BufferError::SizeTooBig if the new length would exceed BUF_MAX_SIZE.
Sourcepub fn incr_write_pos(&mut self, incr: usize) -> Result<()>
pub fn incr_write_pos(&mut self, incr: usize) -> Result<()>
Increments the write position and updates length if needed.
When using with_capacity, this will grow the
internal Vec if needed.
§Errors
Returns BufferError::IncrementTooLarge if the increment is too large
or the new position would exceed BUF_MAX_SIZE.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Resets the buffer for reuse by clearing position and length.
This does not free memory or zero the contents. Use burn
for secure erasure.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_u32(42)?;
assert_eq!(buf.len(), 4);
buf.reset();
assert_eq!(buf.len(), 0);
assert_eq!(buf.pos(), 0);Sourcepub fn burn_free(self)
pub fn burn_free(self)
Consumes the buffer and securely frees its memory.
Equivalent to Dropbear’s buf_burn_free() pattern. Provides explicit
ownership-consuming cleanup.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_bytes(b"secret")?;
buf.burn_free(); // Buffer consumed and securely erasedSourcepub fn as_slice(&self) -> &[u8] ⓘ
pub fn as_slice(&self) -> &[u8] ⓘ
Returns a slice of all valid data in the buffer.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_bytes(b"hello")?;
assert_eq!(buf.as_slice(), b"hello");Sourcepub fn as_mut_slice(&mut self) -> &mut [u8] ⓘ
pub fn as_mut_slice(&mut self) -> &mut [u8] ⓘ
Returns a mutable slice of all valid data.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_bytes(b"hello")?;
buf.as_mut_slice()[0] = b'H';
assert_eq!(buf.as_slice(), b"Hello");Sourcepub fn resize(&mut self, new_size: usize) -> Result<()>
pub fn resize(&mut self, new_size: usize) -> Result<()>
Resizes the buffer, preserving existing data.
§Errors
Returns BufferError::SizeTooBig if new_size exceeds BUF_MAX_SIZE.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.resize(2048)?;
assert_eq!(buf.capacity(), 2048);Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Ensures the buffer has at least the specified additional capacity.
Similar to Vec::reserve.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(100);
buf.reserve(1000);
assert!(buf.capacity() >= 1100);Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Shrinks the buffer capacity to fit the current length.
Frees unused memory.
§Examples
use secbuf::Buffer;
let mut buf = Buffer::new(1024);
buf.put_bytes(b"hello")?;
buf.shrink_to_fit();
assert_eq!(buf.capacity(), 5);Source§impl Buffer
impl Buffer
Sourcepub fn put_u32(&mut self, val: u32) -> Result<()>
pub fn put_u32(&mut self, val: u32) -> Result<()>
Writes a u32 in big-endian format with bounds checking.
Sourcepub fn get_u32(&mut self) -> Result<u32>
pub fn get_u32(&mut self) -> Result<u32>
Reads a u32 in big-endian format with bounds checking.
Sourcepub fn put_u64(&mut self, val: u64) -> Result<()>
pub fn put_u64(&mut self, val: u64) -> Result<()>
Writes a u64 in big-endian format with bounds checking.
Sourcepub fn get_u64(&mut self) -> Result<u64>
pub fn get_u64(&mut self) -> Result<u64>
Reads a u64 in big-endian format with bounds checking.
Sourcepub fn put_bytes(&mut self, bytes: &[u8]) -> Result<()>
pub fn put_bytes(&mut self, bytes: &[u8]) -> Result<()>
Writes bytes with a single bounds check.
Sourcepub fn get_bytes(&mut self, len: usize) -> Result<Vec<u8>>
pub fn get_bytes(&mut self, len: usize) -> Result<Vec<u8>>
Reads bytes, returning an owned Vec.
Sourcepub fn get_bytes_ref(&mut self, len: usize) -> Result<&[u8]>
pub fn get_bytes_ref(&mut self, len: usize) -> Result<&[u8]>
Reads bytes as a slice reference (zero-copy).
Sourcepub fn get_ptr(&self, len: usize) -> Result<&[u8]>
pub fn get_ptr(&self, len: usize) -> Result<&[u8]>
Gets a reference to data at current position without advancing.
Sourcepub fn get_write_ptr(&mut self, len: usize) -> Result<&mut [u8]>
pub fn get_write_ptr(&mut self, len: usize) -> Result<&mut [u8]>
Gets a mutable reference to data at current position (for writing).
Sourcepub fn put_string(&mut self, s: &[u8]) -> Result<()>
pub fn put_string(&mut self, s: &[u8]) -> Result<()>
Writes an SSH-style string (4-byte length prefix + data).
Sourcepub fn get_string(&mut self) -> Result<Vec<u8>>
pub fn get_string(&mut self) -> Result<Vec<u8>>
Reads an SSH-style string (4-byte length prefix + data).
Sourcepub fn eat_string(&mut self) -> Result<()>
pub fn eat_string(&mut self) -> Result<()>
Skips over an SSH-style string without reading the data.
Sourcepub fn put_bytes_fast(&mut self, bytes: &[u8]) -> Result<()>
pub fn put_bytes_fast(&mut self, bytes: &[u8]) -> Result<()>
SIMD-accelerated bulk copy for large buffers (≥64 bytes).
Source§impl Buffer
impl Buffer
Sourcepub unsafe fn put_u32_unchecked(&mut self, val: u32)
pub unsafe fn put_u32_unchecked(&mut self, val: u32)
Writes a u32 in big-endian format without bounds checking.
§Safety
Caller MUST guarantee: self.pos + 4 <= self.capacity().
Sourcepub unsafe fn get_u32_unchecked(&mut self) -> u32
pub unsafe fn get_u32_unchecked(&mut self) -> u32
Reads a u32 in big-endian format without bounds checking.
§Safety
Caller MUST guarantee: self.pos + 4 <= self.len.
Sourcepub unsafe fn put_u64_unchecked(&mut self, val: u64)
pub unsafe fn put_u64_unchecked(&mut self, val: u64)
Writes a u64 in big-endian format without bounds checking.
§Safety
Caller MUST guarantee: self.pos + 8 <= self.capacity().
Sourcepub unsafe fn get_u64_unchecked(&mut self) -> u64
pub unsafe fn get_u64_unchecked(&mut self) -> u64
Reads a u64 in big-endian format without bounds checking.
§Safety
Caller MUST guarantee: self.pos + 8 <= self.len.
Sourcepub unsafe fn put_bytes_unchecked(&mut self, bytes: &[u8])
pub unsafe fn put_bytes_unchecked(&mut self, bytes: &[u8])
Writes bytes without bounds checking.
§Safety
Caller MUST guarantee: self.pos + bytes.len() <= self.capacity().