1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
* Spare Buffer
* This is free and unencumbered software released into the public domain.
*/
//! A wrapper around [**`Vec<T>`**](std::vec::Vec) that gives access to the
//! "spare" capacity of the vector as a `&mut[T]` slice.
//!
//! Useful to allocate ["spare" capacity](std::vec::Vec::spare_capacity_mut) at
//! the end of the underlying vector and fill it *directly*, e.g. by
//! [`read()`](std::io::Read::read)ing from a file or stream, **without**
//! initialize the memory first. Once filled, the vector can be "extended" into
//! the previously allocated spare capacity.
//!
//! The following two steps are always required, usually performed in a loop:
//! 1. [Allocate](crate::SpareBuffer::allocate_spare) a new "spare" buffer of
//! appropriate length.
//! 2. [Commit](crate::SpareBuffer::commit) the "spare" buffer, once it has
//! been filled with some valid data.
//!
//! Note that, after step #1, the "spare" buffer is **not** considered a
//! valid part of the underlying vector yet. Committing the data, in
//! step #2, effectively *appends* the contents of the "spare" buffer to
//! the underlying vector, but **without** copying the data.
//!
//! It is **not** necessary to fill *all* of the "spare" buffer; only the first
//! `n` elements may be committed. However, *all* elements to be committed
//! **must** have been initialized, or the contents of the underlying vector
//! are ***unspecified*** after the commit!
//!
//! # Example #1
//!
//! For starters, fill a pre-allocated [**`SpareBuffer`**](crate::SpareBuffer)
//! with some numbers:
//! ```
//! fn main() {
//! let mut vec: Vec<u8> = Vec::with_capacity(128);
//! let mut buffer = SpareBuffer::from(&mut vec, None);
//!
//! let spare = buffer.allocate_spare(NonZeroUsize::new(100).unwrap());
//! for i in 0..50 {
//! spare[i] = i as u8;
//! }
//!
//! // Whoops: only &spare[0..50] was initialized, but 100 elements are committed!
//! buffer.commit(100).expect("Failed to commit!");
//!
//! println!("Expect valid numbers:");
//! println!("{:?}\n", &vec[..50]);
//!
//! println!("Expect \"unspecified\" garbage:");
//! println!("{:?}\n", &vec[50..]);
//! }
//! ```
//!
//! # Example #2
//!
//! Read a file into a vector, chunk by chunk, using a
//! [**`SpareBuffer`**](crate::SpareBuffer) to accumulate all data:
//! ```
//! fn main() {
//! let mut vec: Vec<u8> = Vec::with_capacity(1048576);
//! let mut buffer = SpareBuffer::from(&mut vec, NonZeroUsize::new(10485760));
//!
//! let chunk_size = NonZeroUsize::new(4096).unwrap();
//! let mut file = File::open("input.dat").expect("Failed to open input file!");
//!
//! loop {
//! let spare = buffer.allocate_spare(chunk_size);
//! let count = file.read(spare).expect("File read error encountered!");
//! if count > 0 {
//! buffer.commit(count).expect("Failed to commit!");
//! } else {
//! break; /* EOF*/
//! }
//! }
//!
//! println!("Length: {:?}", vec.len());
//! }
//! ```
pub use SpareBuffer;
pub use Primitive;