libsignal_protocol/
buffer.rs

1use std::{
2    cmp::{Ord, Ordering},
3    fmt::{self, Debug, Formatter},
4    io::{self, Write},
5    mem,
6    ops::{Index, IndexMut},
7};
8
9/// A byte buffer (e.g. `Vec<u8>`).
10pub struct Buffer {
11    raw: *mut sys::signal_buffer,
12}
13
14impl Buffer {
15    /// Create a new empty buffer.
16    pub fn new() -> Buffer { Buffer::with_capacity(0) }
17
18    pub(crate) unsafe fn from_raw(raw: *mut sys::signal_buffer) -> Buffer {
19        assert!(!raw.is_null());
20        Buffer { raw }
21    }
22
23    /// Create a new buffer with the provided size.
24    pub fn with_capacity(capacity: usize) -> Buffer {
25        unsafe { Buffer::from_raw(sys::signal_buffer_alloc(capacity)) }
26    }
27
28    /// How many bytes are in this buffer?
29    pub fn len(&self) -> usize { unsafe { sys::signal_buffer_len(self.raw) } }
30
31    /// Is the buffer empty?
32    pub fn is_empty(&self) -> bool { self.len() > 0 }
33
34    /// Extract the underlying raw pointer.
35    ///
36    /// # Note
37    ///
38    /// It is the user's responsibility to ensure the buffer is later free'd
39    /// (e.g. with [`Buffer::from_raw`] or [`sys::signal_buffer_free`]).
40    pub fn into_raw(self) -> *mut sys::signal_buffer {
41        let raw = self.raw;
42        mem::forget(self);
43        raw
44    }
45
46    /// Get an immutable reference to the underlying data.
47    pub fn as_slice(&self) -> &[u8] {
48        unsafe {
49            let ptr = sys::signal_buffer_data(self.raw);
50            assert!(!ptr.is_null());
51            std::slice::from_raw_parts(ptr, self.len())
52        }
53    }
54
55    /// Get a mutable reference to the underlying data.
56    pub fn as_slice_mut(&mut self) -> &mut [u8] {
57        unsafe {
58            let len = self.len();
59            let ptr = sys::signal_buffer_data(self.raw);
60            assert!(!ptr.is_null());
61            std::slice::from_raw_parts_mut(ptr, len)
62        }
63    }
64
65    /// Append some data to this buffer.
66    ///
67    /// # Note
68    ///
69    /// Every append results in a re-allocation of the underlying buffer.
70    pub fn append(&mut self, data: &[u8]) {
71        unsafe {
72            self.raw =
73                sys::signal_buffer_append(self.raw, data.as_ptr(), data.len());
74        }
75    }
76}
77
78impl Ord for Buffer {
79    fn cmp(&self, other: &Buffer) -> Ordering {
80        let ret = unsafe { sys::signal_buffer_compare(self.raw, other.raw) };
81
82        if ret < 0 {
83            Ordering::Less
84        } else if ret > 0 {
85            Ordering::Greater
86        } else {
87            Ordering::Equal
88        }
89    }
90}
91
92impl PartialOrd for Buffer {
93    fn partial_cmp(&self, other: &Buffer) -> Option<Ordering> {
94        Some(self.cmp(other))
95    }
96}
97
98impl PartialEq for Buffer {
99    fn eq(&self, other: &Buffer) -> bool { self.cmp(other) == Ordering::Equal }
100}
101
102impl Eq for Buffer {}
103
104impl Default for Buffer {
105    fn default() -> Self { Self::new() }
106}
107
108impl Debug for Buffer {
109    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
110        self.as_slice().fmt(f)
111    }
112}
113
114impl From<Vec<u8>> for Buffer {
115    fn from(other: Vec<u8>) -> Buffer { Buffer::from(other.as_slice()) }
116}
117
118impl<'a> From<&'a [u8]> for Buffer {
119    fn from(other: &'a [u8]) -> Buffer {
120        unsafe {
121            Buffer::from_raw(sys::signal_buffer_create(
122                other.as_ptr(),
123                other.len(),
124            ))
125        }
126    }
127}
128
129impl AsRef<[u8]> for Buffer {
130    fn as_ref(&self) -> &[u8] { self.as_slice() }
131}
132
133impl AsMut<[u8]> for Buffer {
134    fn as_mut(&mut self) -> &mut [u8] { self.as_slice_mut() }
135}
136
137impl<T> Index<T> for Buffer
138where
139    [u8]: Index<T>,
140{
141    type Output = <[u8] as Index<T>>::Output;
142
143    fn index(&self, ix: T) -> &Self::Output { self.as_slice().index(ix) }
144}
145
146impl<T> IndexMut<T> for Buffer
147where
148    [u8]: IndexMut<T>,
149{
150    fn index_mut(&mut self, ix: T) -> &mut Self::Output {
151        self.as_slice_mut().index_mut(ix)
152    }
153}
154
155impl Write for Buffer {
156    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
157        self.append(data);
158        Ok(data.len())
159    }
160
161    fn flush(&mut self) -> io::Result<()> { Ok(()) }
162}
163
164impl Clone for Buffer {
165    fn clone(&self) -> Buffer {
166        unsafe {
167            let raw = sys::signal_buffer_copy(self.raw);
168            assert!(!raw.is_null());
169            Buffer { raw }
170        }
171    }
172}
173
174impl Drop for Buffer {
175    fn drop(&mut self) {
176        unsafe {
177            sys::signal_buffer_free(self.raw);
178        }
179    }
180}
181
182#[cfg(test)]
183mod tests {
184    use super::*;
185
186    #[test]
187    fn create_and_delete() {
188        let buffer = Buffer::new();
189        drop(buffer);
190    }
191
192    #[test]
193    fn create_with_capacity() {
194        let cap = 12345;
195        let buffer = Buffer::with_capacity(cap);
196        assert_eq!(buffer.len(), cap);
197    }
198
199    #[test]
200    fn get_an_item() {
201        let mut buffer = Buffer::with_capacity(128);
202        buffer[10] = 0xde;
203        buffer[11] = 0xad;
204        buffer[12] = 0xbe;
205        buffer[13] = 0xef;
206
207        let dead_beef = &buffer[10..14];
208        assert_eq!(dead_beef, &[0xde, 0xad, 0xbe, 0xef]);
209    }
210
211    #[test]
212    fn write_to_a_buffer() {
213        let mut buffer = Buffer::new();
214
215        write!(buffer, "Hello").unwrap();
216        write!(buffer, ",").unwrap();
217        writeln!(buffer, " World!").unwrap();
218
219        let got = std::str::from_utf8(buffer.as_slice()).unwrap();
220        assert_eq!("Hello, World!\n", got);
221    }
222}