karyon_net/codec/
buffer.rs

1pub type ByteBuffer = Buffer;
2
3#[derive(Debug)]
4pub struct Buffer {
5    inner: Vec<u8>,
6    len: usize,
7    max_length: usize,
8}
9
10impl Buffer {
11    /// Constructs a new, empty Buffer.
12    pub fn new(max_length: usize) -> Self {
13        Self {
14            max_length,
15            inner: Vec::new(),
16            len: 0,
17        }
18    }
19
20    /// Returns the number of elements in the buffer.
21    #[allow(dead_code)]
22    pub fn len(&self) -> usize {
23        self.len
24    }
25
26    /// Resizes the buffer in-place so that `len` is equal to `new_size`.
27    pub fn resize(&mut self, new_size: usize) {
28        // Check the Buffer doesn't grow beyond its max length.
29        assert!(
30            self.max_length > new_size,
31            "buffer resize to {} overflows the buffer max_length ({})",
32            new_size,
33            self.max_length
34        );
35        // Make sure the vector can contain the data.
36        // Note 1: reserve() is a no-op if the vector capacity is already large
37        // enough, but we don't want to cause the unsigned to underflow.
38        // Note 2: we don't shrink the vector memory if the length is reduced,
39        // as this operation might be costly and the released memory expected to
40        // be small.
41        // Note 3: the vector capacity (aka allocated memory) might be larger
42        // than max_length due to the allocator doing over-provisioning, but it
43        // is guaranteed that the data length won't overflow.
44        if new_size > self.len {
45            self.inner.reserve(new_size - self.len);
46        }
47        // This is a no-op if the new_size is greater or equal to self.len
48        self.inner.truncate(new_size);
49        self.len = new_size;
50    }
51
52    /// Appends all elements in a slice to the buffer.
53    pub fn extend_from_slice(&mut self, bytes: &[u8]) {
54        self.resize(self.len + bytes.len());
55        self.inner.extend_from_slice(bytes);
56    }
57
58    /// Shortens the buffer, dropping the first `cnt` bytes and keeping the
59    /// rest.
60    pub fn advance(&mut self, cnt: usize) {
61        assert!(
62            self.len >= cnt,
63            "buffer advance of {} underflows the buffer length ({})",
64            cnt,
65            self.len
66        );
67        self.inner.rotate_left(cnt);
68        self.resize(self.len - cnt);
69    }
70
71    /// Returns `true` if the buffer contains no elements.
72    pub fn is_empty(&self) -> bool {
73        self.len == 0
74    }
75}
76
77impl AsMut<[u8]> for Buffer {
78    fn as_mut(&mut self) -> &mut [u8] {
79        &mut self.inner[..self.len]
80    }
81}
82
83impl AsRef<[u8]> for Buffer {
84    fn as_ref(&self) -> &[u8] {
85        &self.inner[..self.len]
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn test_buffer() {
95        let mut buf = Buffer::new(32);
96        assert_eq!(&[] as &[u8], buf.as_ref());
97        assert_eq!(0, buf.len());
98        assert_eq!(true, buf.is_empty());
99
100        buf.extend_from_slice(&[1, 2, 3, 4, 5]);
101        assert_eq!(&[1, 2, 3, 4, 5], buf.as_ref());
102        assert_eq!(5, buf.len());
103        assert_eq!(false, buf.is_empty());
104
105        buf.advance(2);
106        assert_eq!(&[3, 4, 5], buf.as_ref());
107        assert_eq!(3, buf.len());
108        assert_eq!(false, buf.is_empty());
109
110        buf.extend_from_slice(&[6, 7, 8]);
111        assert_eq!(&[3, 4, 5, 6, 7, 8], buf.as_ref());
112        assert_eq!(6, buf.len());
113        assert_eq!(false, buf.is_empty());
114
115        buf.advance(4);
116        assert_eq!(&[7, 8], buf.as_ref());
117        assert_eq!(2, buf.len());
118        assert_eq!(false, buf.is_empty());
119
120        buf.advance(2);
121        assert_eq!(&[] as &[u8], buf.as_ref());
122        assert_eq!(0, buf.len());
123        assert_eq!(true, buf.is_empty());
124    }
125
126    #[test]
127    #[should_panic(expected = "buffer resize to 9 overflows the buffer max_length (8)")]
128    fn test_buffer_resize_overflow() {
129        let mut buf = Buffer::new(8);
130        buf.extend_from_slice(&[1, 2, 3, 4, 5, 6, 7, 8, 9]);
131    }
132
133    #[test]
134    #[should_panic(expected = "buffer advance of 5 underflows the buffer length (4)")]
135    fn test_buffer_advance_underflow() {
136        let mut buf = Buffer::new(8);
137        buf.extend_from_slice(&[1, 2, 3, 4]);
138        buf.advance(5);
139    }
140}