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
    }
}