mirror of
https://git.proxmox.com/git/proxmox
synced 2025-05-29 21:14:18 +00:00
tools/byte_buffer: add examples and docs
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
6fffca783e
commit
c734a627a8
@ -6,7 +6,6 @@
|
||||
//! ```
|
||||
//! # use std::io::Read;
|
||||
//! # use proxmox::tools::byte_buffer::ByteBuffer;
|
||||
//!
|
||||
//! fn code<T: Read>(input: &mut T) -> std::io::Result<Box<[u8]>> {
|
||||
//! let mut buffer = ByteBuffer::new();
|
||||
//! let amount = buffer.read_from(input)?;
|
||||
@ -23,6 +22,10 @@ use crate::tools::vec;
|
||||
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
/// A Buffer that holds bytes (u8)
|
||||
/// has convenience methods for reading (with any reader that
|
||||
/// implements std::io::Read or tokio::io::AsyncRead) onto the back
|
||||
/// and consuming from the front
|
||||
pub struct ByteBuffer {
|
||||
buf: Box<[u8]>,
|
||||
data_size: usize,
|
||||
@ -30,6 +33,8 @@ pub struct ByteBuffer {
|
||||
}
|
||||
|
||||
impl ByteBuffer {
|
||||
|
||||
/// Creates a new instance with a default capacity of 4096
|
||||
pub fn new() -> Self {
|
||||
Self::with_capacity(4096)
|
||||
}
|
||||
@ -42,6 +47,7 @@ impl ByteBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the length of the data in the Buffer
|
||||
pub fn data_size(&self) -> usize {
|
||||
self.data_size
|
||||
}
|
||||
@ -58,6 +64,25 @@ impl ByteBuffer {
|
||||
self.data_size >= self.capacity
|
||||
}
|
||||
|
||||
/// Sets the length of the data. Useful if data was manually added
|
||||
/// with a mutable slice (e.g. from [get_free_mut_slice](#method.get_free_mut_slice)).
|
||||
///
|
||||
/// Panics when new size would be greater than capacity.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// # use proxmox::tools::byte_buffer::ByteBuffer;
|
||||
/// let mut buf = ByteBuffer::new();
|
||||
/// buf.get_free_mut_slice()[..1].copy_from_slice(&[1u8]);
|
||||
/// buf.add_size(1);
|
||||
/// ```
|
||||
///
|
||||
/// This code will panic:
|
||||
/// ```should_panic
|
||||
/// # use proxmox::tools::byte_buffer::ByteBuffer;
|
||||
/// let mut buf = ByteBuffer::with_capacity(128);
|
||||
/// buf.add_size(256);
|
||||
/// ```
|
||||
pub fn add_size(&mut self, size: usize) {
|
||||
if self.data_size + size > self.capacity {
|
||||
panic!("size bigger than capacity!");
|
||||
@ -65,14 +90,45 @@ impl ByteBuffer {
|
||||
self.data_size += size;
|
||||
}
|
||||
|
||||
/// Gets an immutable reference to the data in the buffer
|
||||
/// Example:
|
||||
/// ```
|
||||
/// # use proxmox::tools::byte_buffer::ByteBuffer;
|
||||
/// let mut buf = ByteBuffer::new();
|
||||
/// buf.get_free_mut_slice()[..2].copy_from_slice(&[1u8, 2u8]);
|
||||
/// buf.add_size(2);
|
||||
/// assert_eq!(buf.get_data_slice(), &[1u8, 2u8]);
|
||||
/// ```
|
||||
pub fn get_data_slice(&self) -> &[u8] {
|
||||
&self.buf[..self.data_size]
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the free section of the
|
||||
/// Buffer. There are no guarantees about the content of the
|
||||
/// free part of the Buffer (may even be uninitialized).
|
||||
/// see [add_size](#method.add_size) for a usage example.
|
||||
pub fn get_free_mut_slice(&mut self) -> &mut [u8] {
|
||||
&mut self.buf[self.data_size..self.capacity]
|
||||
}
|
||||
|
||||
/// Consumes up to max_amount of data from the front
|
||||
/// of the buffer. If there was less than max_amount present,
|
||||
/// it will return as much data as there was in the buffer.
|
||||
/// The rest of the data will be moved to the front, and
|
||||
/// the data size will be updated accordingly.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// # use proxmox::tools::byte_buffer::ByteBuffer;
|
||||
/// let mut buf = ByteBuffer::new();
|
||||
/// buf.get_free_mut_slice()[..2].copy_from_slice(&[1u8, 2u8]);
|
||||
/// buf.add_size(2);
|
||||
/// assert_eq!(buf.data_size(), 2);
|
||||
///
|
||||
/// let data = buf.consume(100);
|
||||
/// assert_eq!(data, vec![1u8, 2u8].into_boxed_slice());
|
||||
/// assert!(buf.is_empty());
|
||||
/// ```
|
||||
pub fn consume(&mut self, max_amount: usize) -> Box<[u8]> {
|
||||
let size = min(max_amount, self.data_size);
|
||||
let mut tmp = Vec::with_capacity(size);
|
||||
@ -82,12 +138,27 @@ impl ByteBuffer {
|
||||
tmp.into_boxed_slice()
|
||||
}
|
||||
|
||||
/// Takes a reader and reads into the back of the buffer (up to the
|
||||
/// free space in the buffer) and updates its size accordingly.
|
||||
///
|
||||
/// Example:
|
||||
/// ```norun
|
||||
/// // create some reader
|
||||
/// let reader = ...;
|
||||
///
|
||||
/// let mut buf = ByteBuffer::new();
|
||||
/// let res = buf.read_from(reader);
|
||||
/// // do something with the buffer
|
||||
/// ...
|
||||
/// ```
|
||||
pub fn read_from<T: Read>(&mut self, input: &mut T) -> Result<usize> {
|
||||
let amount = input.read(self.get_free_mut_slice())?;
|
||||
self.add_size(amount);
|
||||
Ok(amount)
|
||||
}
|
||||
|
||||
/// Same as read_from, but for reader that implement tokio::io::AsyncRead.
|
||||
/// See [read_from](#method.read_from) for an example
|
||||
pub async fn read_from_async<T: AsyncReadExt + Unpin>(&mut self, input: &mut T) -> Result<usize> {
|
||||
let amount = input.read(self.get_free_mut_slice()).await?;
|
||||
self.add_size(amount);
|
||||
|
Loading…
Reference in New Issue
Block a user