SpareBuffer

Struct SpareBuffer 

Source
pub struct SpareBuffer<'a, T>
where T: Primitive,
{ /* private fields */ }
Expand description

A wrapper around Vec<T> that provides access to the “spare” capacity of the vector as a &mut[T] slice.

See module level documentation for more information.

Implementations§

Source§

impl<'a, T> SpareBuffer<'a, T>
where T: Primitive,

Source

pub fn from(buffer: &'a mut Vec<T>, limit: Option<NonZeroUsize>) -> Self

Creates a new SpareBuffer from an existing vector.

An optional limit for the length of the vector can be specified. The commit() fails, if it would exceed this limit.

Examples found in repository?
examples/fill_buffer.rs (line 11)
9fn main() {
10    let mut vec: Vec<u8> = Vec::with_capacity(128);
11    let mut buffer = SpareBuffer::from(&mut vec, None);
12    
13    let spare = buffer.allocate_spare(NonZeroUsize::new(100).unwrap());
14    for i in 0..50 {
15        spare[i] = i as u8;
16    }
17
18    // Whoops: only &spare[0..50] was initialized, but 100 elements are committed!
19    buffer.commit(100).expect("Failed to commit!");
20
21    println!("Expect valid numbers:");
22    println!("{:?}\n", &vec[..50]);
23
24    println!("Expect \"unspecified\" garbage:");
25    println!("{:?}\n", &vec[50..]);
26}
More examples
Hide additional examples
examples/read_file.rs (line 13)
11fn main() {
12    let mut vec: Vec<u8> = Vec::with_capacity(1048576);
13    let mut buffer = SpareBuffer::from(&mut vec, NonZeroUsize::new(10485760));
14    
15    let chunk_size = NonZeroUsize::new(4096).unwrap();
16    let mut file = File::open("input.dat").expect("Failed to open input file!");
17
18    loop {
19        let spare = buffer.allocate_spare(chunk_size);
20        let count = file.read(spare).expect("File read error encountered!");
21        if count > 0 {
22            buffer.commit(count).expect("Failed to commit!");
23        } else {
24            break; /* EOF*/
25        }
26    }
27
28    println!("Length: {:?}", vec.len());
29}
Source

pub fn len(&self) -> usize

Returns the number of “committed” elements in the underlying vector. This is equivalent to Vec::len().

Source

pub fn is_empty(&self) -> bool

Returns true if the underlying vector contains no “committed” elements. This is equivalent to Vec::is_empty().

Source

pub fn limit(&self) -> Option<NonZeroUsize>

Returns the length limit, if a limit has been specified. Otherwise None is returned.

Source

pub fn data(&self) -> &[T]

Returns a &[T] slice of all “committed” elements in the underlying vector. This is equivalent to Vec::as_slice().

Source

pub fn allocate_spare(&mut self, length: NonZeroUsize) -> &mut [T]

Allocates a “spare” buffer of the specified length.

Reserves capacity for at least length additional elements in the underlying vector. May reserve more space to speculatively avoid frequent reallocations. Does nothing, if the unused “spare” capacity of the underlying vector is already sufficient.

Returns a &mut[T] slice which allows the caller to access the allocated “spare” buffer. No guarantees are provided about the initial contents of the buffer! It is recommended that the caller only writes data to the slice instead of reading its contents.

The returned &mut[T] slice can be passed to Read::read() or similar I/O routines.

The “spare” buffer is not considered to be a valid part of the underlying vector, until the commit() function is called eventually.

Examples found in repository?
examples/fill_buffer.rs (line 13)
9fn main() {
10    let mut vec: Vec<u8> = Vec::with_capacity(128);
11    let mut buffer = SpareBuffer::from(&mut vec, None);
12    
13    let spare = buffer.allocate_spare(NonZeroUsize::new(100).unwrap());
14    for i in 0..50 {
15        spare[i] = i as u8;
16    }
17
18    // Whoops: only &spare[0..50] was initialized, but 100 elements are committed!
19    buffer.commit(100).expect("Failed to commit!");
20
21    println!("Expect valid numbers:");
22    println!("{:?}\n", &vec[..50]);
23
24    println!("Expect \"unspecified\" garbage:");
25    println!("{:?}\n", &vec[50..]);
26}
More examples
Hide additional examples
examples/read_file.rs (line 19)
11fn main() {
12    let mut vec: Vec<u8> = Vec::with_capacity(1048576);
13    let mut buffer = SpareBuffer::from(&mut vec, NonZeroUsize::new(10485760));
14    
15    let chunk_size = NonZeroUsize::new(4096).unwrap();
16    let mut file = File::open("input.dat").expect("Failed to open input file!");
17
18    loop {
19        let spare = buffer.allocate_spare(chunk_size);
20        let count = file.read(spare).expect("File read error encountered!");
21        if count > 0 {
22            buffer.commit(count).expect("Failed to commit!");
23        } else {
24            break; /* EOF*/
25        }
26    }
27
28    println!("Length: {:?}", vec.len());
29}
Source

pub fn commit(&mut self, additional: usize) -> IoResult<()>

Commits the first additional elements of the “spare” buffer.

The underlying vector is extended into the previously allocated “spare” buffer, by increasing its length, so that the first additional elements in the “spare” buffer effectively are appended to the vector without copying the data.

All elements to be committed fom the “spare” buffer must have been initialized, i.e. the whole of &spare[0..additional] must have been filled with valid data. Otherwise, the contents of the underlying vector are unspecified after the commit 😨

This function always invalidates the current “spare” buffer. A new “spare” buffer must be allocated in order to append more data!

§Errors

If a length limit has been specified, then this function will fail, if adding additional more elements to the underlying vector would cause its total length to exceed the specified limit. Otherwise, the function always returns Ok(()).

§Panics

Panics if additional is greater than the available “spare” capacity, or if no “spare” buffer was allocated before!

A panic may also occur, if the new length would overflow usize::MAX.

Examples found in repository?
examples/fill_buffer.rs (line 19)
9fn main() {
10    let mut vec: Vec<u8> = Vec::with_capacity(128);
11    let mut buffer = SpareBuffer::from(&mut vec, None);
12    
13    let spare = buffer.allocate_spare(NonZeroUsize::new(100).unwrap());
14    for i in 0..50 {
15        spare[i] = i as u8;
16    }
17
18    // Whoops: only &spare[0..50] was initialized, but 100 elements are committed!
19    buffer.commit(100).expect("Failed to commit!");
20
21    println!("Expect valid numbers:");
22    println!("{:?}\n", &vec[..50]);
23
24    println!("Expect \"unspecified\" garbage:");
25    println!("{:?}\n", &vec[50..]);
26}
More examples
Hide additional examples
examples/read_file.rs (line 22)
11fn main() {
12    let mut vec: Vec<u8> = Vec::with_capacity(1048576);
13    let mut buffer = SpareBuffer::from(&mut vec, NonZeroUsize::new(10485760));
14    
15    let chunk_size = NonZeroUsize::new(4096).unwrap();
16    let mut file = File::open("input.dat").expect("Failed to open input file!");
17
18    loop {
19        let spare = buffer.allocate_spare(chunk_size);
20        let count = file.read(spare).expect("File read error encountered!");
21        if count > 0 {
22            buffer.commit(count).expect("Failed to commit!");
23        } else {
24            break; /* EOF*/
25        }
26    }
27
28    println!("Length: {:?}", vec.len());
29}
Source

pub unsafe fn commit_unchecked(&mut self, additional: usize)

The same as commit() but without any checks.

This function is unsafe, for obvious reasons, and therefore should be used with great care!

Auto Trait Implementations§

§

impl<'a, T> Freeze for SpareBuffer<'a, T>

§

impl<'a, T> RefUnwindSafe for SpareBuffer<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Send for SpareBuffer<'a, T>
where T: Send,

§

impl<'a, T> Sync for SpareBuffer<'a, T>
where T: Sync,

§

impl<'a, T> Unpin for SpareBuffer<'a, T>

§

impl<'a, T> !UnwindSafe for SpareBuffer<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.