libsignal_protocol/
buffer.rs1use std::{
2 cmp::{Ord, Ordering},
3 fmt::{self, Debug, Formatter},
4 io::{self, Write},
5 mem,
6 ops::{Index, IndexMut},
7};
8
9pub struct Buffer {
11 raw: *mut sys::signal_buffer,
12}
13
14impl Buffer {
15 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 pub fn with_capacity(capacity: usize) -> Buffer {
25 unsafe { Buffer::from_raw(sys::signal_buffer_alloc(capacity)) }
26 }
27
28 pub fn len(&self) -> usize { unsafe { sys::signal_buffer_len(self.raw) } }
30
31 pub fn is_empty(&self) -> bool { self.len() > 0 }
33
34 pub fn into_raw(self) -> *mut sys::signal_buffer {
41 let raw = self.raw;
42 mem::forget(self);
43 raw
44 }
45
46 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 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 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}