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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
//! A dynamic buffer encapsulates memory storage that may be automatically resized //! as required, where the memory is divided into two regions: readable bytes followed by writable //! bytes. These memory regions are internal to the dynamic buffer, but direct access to the //! elements is provided to permit them to be efficiently used with I/O operations. //! //! ``` note //! Note: Such as the send or receive operations of a socket. The readable bytes would be used as //! the constant buffer sequence for send, and the writable bytes used as the mutable buffer //! sequence for receive. //! ``` //! //! Data written to the writable bytes of a dynamic buffer object is appended to the readable bytes //! of the same object. /// `VecBuf` is an effective [dynamic buffer v1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1790r0.html) /// implement, which tries to reduce reallocation and mem-moving. /// /// If `commit` and `consume` speed matches(`len()` is always less than `min_write`), this buffer /// would allocate only once. /// /// # Example /// ``` /// use dyn_buf::VecBuf; /// let mut buf = VecBuf::new(10); /// /// let t = buf.prepare(4); /// assert_eq!(t.len(), 4); /// /// // write data to prepared buffer /// t[..3].copy_from_slice(&[1, 2, 3]); /// assert_eq!(buf.data(), &[]); /// /// buf.commit(3); /// assert_eq!(buf.data(), &[1, 2, 3]); /// /// buf.consume(2); /// assert_eq!(buf.data(), &[3]); /// /// let t = buf.prepare_at_least(2); /// assert!(t.len() >= 2); /// t[..2].copy_from_slice(&[4, 5]); /// assert_eq!(buf.data(), &[3]); /// /// buf.commit(2); /// assert_eq!(buf.data(), &[3, 4, 5]); /// /// buf.consume(2); /// assert_eq!(buf.data(), &[5]); /// /// assert_eq!(buf.into_vec(), vec![5]); /// ``` #[derive(Default)] pub struct VecBuf { buf: Vec<u8>, wrote: usize, read: usize, min_write: usize, } // impl dynamic buffer impl VecBuf { /// Returns the number of readable bytes. #[inline] pub fn len(&self) -> usize { self.wrote - self.read } /// Returns `true` if buffer contains no readable bytes. #[inline] pub fn is_empty(&self) -> bool { self.read >= self.wrote } /// Returns the maximum number of bytes, both readable and writable, that can be held by `self` /// without requiring reallocation. pub fn capacity(&self) -> usize { self.buf.len() - self.len() } /// Returns a constant buffer sequence u that represents the readable bytes. #[inline] pub fn data(&self) -> &[u8] { &self.buf[self.read..self.wrote] } /// Returns a mutable buffer sequence u representing the writable bytes, and where /// `buffer_size(u) == amt`. /// /// The dynamic buffer reallocates memory as required. All constant or mutable buffer sequences /// previously obtained using data() or prepare() are invalidated. /// /// Panic: length_error if size() + `amt` exceeds max_size(). pub fn prepare(&mut self, amt: usize) -> &mut [u8] { self.reserve(amt); &mut self.buf[self.wrote..self.wrote + amt] } /// Returns a mutable buffer sequence u representing the writable bytes, and where /// `buffer_size(u) >= amt`. /// /// The dynamic buffer reallocates memory as required. All constant or mutable buffer sequences /// previously obtained using data() or prepare() are invalidated. /// /// Panic: length_error if size() + `amt` exceeds max_size(). pub fn prepare_at_least(&mut self, amt: usize) -> &mut [u8] { self.reserve(amt); &mut self.buf[self.wrote..] } /// Appends `amt` bytes from the start of the writable bytes to the end of the readable bytes. /// /// The remainder of the writable bytes are discarded. If `amt` is greater than the number of /// writable bytes, all writable bytes are appended to the readable bytes. All constant /// or mutable buffer sequences previously obtained using data() or prepare() are invalidated. #[inline] pub fn commit(&mut self, amt: usize) { debug_assert!(self.wrote + amt <= self.buf.len()); self.wrote += amt } /// Removes `amt` bytes from beginning of the readable bytes. /// /// If `amt` is greater than the number of readable bytes, all readable bytes are removed. All /// constant or mutable buffer sequences previously obtained using data() or prepare() are /// invalidated. #[inline] pub fn consume(&mut self, amt: usize) { debug_assert!(amt <= self.len()); if amt >= self.len() { self.wrote = 0; self.read = 0; } else { self.read += amt; } } } // impl helpers impl VecBuf { /// create a `VecBuf` with `min_write` /// /// `prepare_at_least` will return a buffer at least `min_write` bytes. /// # Example ///``` /// use dyn_buf::VecBuf; /// let min_write = 5; /// let mut buf = VecBuf::new(min_write); /// let t = buf.prepare_at_least(0); /// assert!(t.len() >= min_write); /// t[..2].copy_from_slice(&[1,2]); /// buf.commit(2); /// let t = buf.prepare_at_least(0); /// assert!(t.len() >= min_write); /// ``` pub fn new(min_write: usize) -> Self { Self { min_write, ..Default::default() } } /// Reserves capacity for at least `amt` bytes to be wrote pub fn reserve(&mut self, amt: usize) { let amt = amt.max(if self.buf.is_empty() { self.min_write * 2 } else { self.min_write }); if self.buf.len() < self.wrote + amt { if self.buf.len() >= self.len() + amt { self.move_data_to_front(); return; } self.grow(amt); } } fn move_data_to_front(&mut self) { self.buf.copy_within(self.read..self.wrote, 0); self.wrote -= self.read; self.read = 0; } /// Grow capacity at least `amt` bytes pub fn grow(&mut self, amt: usize) { self.buf.reserve(amt.max(self.buf.len())); self.buf.resize(self.buf.capacity(), 0); } /// Write all bytes of `buf` into `self` pub fn write_all(&mut self, buf: &[u8]) { self.prepare(buf.len()).copy_from_slice(buf); self.commit(buf.len()); } /// Converts `self` into a vector without clones or allocation. The resulting vector contains /// all the readable bytes pub fn into_vec(mut self) -> Vec<u8> { if self.read > 0 { self.move_data_to_front(); } self.buf.truncate(self.wrote); self.buf } }