1use super::utils::{safe_copy, set_zero};
2use libc;
3use nix::errno::Errno;
4use std::slice;
5use std::{
6 fmt,
7 ops::{Deref, DerefMut},
8};
9
10use fail::fail_point;
11
12#[repr(C, align(1))]
22pub struct Buffer {
23 buf_ptr: *mut libc::c_void,
24 pub(crate) size: u32,
26 pub(crate) cap: u32,
28}
29
30impl fmt::Debug for Buffer {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 write!(f, "buffer {:p} size {}", self.get_raw(), self.len())
33 }
34}
35
36unsafe impl Send for Buffer {}
37
38unsafe impl Sync for Buffer {}
39
40pub const MIN_ALIGN: u32 = 512;
41pub const MAX_BUFFER_SIZE: usize = 1 << 31;
42
43fn is_aligned(offset: usize, size: usize) -> bool {
44 return (offset & (MIN_ALIGN as usize - 1) == 0) && (size & (MIN_ALIGN as usize - 1) == 0);
45}
46
47impl Buffer {
48 #[inline]
55 pub fn aligned(size: i32) -> Result<Buffer, Errno> {
56 let mut _buf = Self::_alloc(MIN_ALIGN, size)?;
57 fail_point!("alloc_buf", |_| {
58 rand_buffer(&mut _buf);
59 return Ok(_buf);
60 });
61 return Ok(_buf);
62 }
63
64 #[inline]
73 pub fn aligned_by(size: i32, align: u32) -> Result<Buffer, Errno> {
74 let mut _buf = Self::_alloc(align, size)?;
75 fail_point!("alloc_buf", |_| {
76 rand_buffer(&mut _buf);
77 return Ok(_buf);
78 });
79 return Ok(_buf);
80 }
81
82 #[inline]
89 pub fn alloc(size: i32) -> Result<Buffer, Errno> {
90 let mut _buf = Self::_alloc(0, size)?;
91 fail_point!("alloc_buf", |_| {
92 rand_buffer(&mut _buf);
93 return Ok(_buf);
94 });
95 return Ok(_buf);
96 }
97
98 #[inline]
102 fn _alloc(align: u32, size: i32) -> Result<Self, Errno> {
103 assert!(size > 0);
104 let mut ptr: *mut libc::c_void = std::ptr::null_mut();
105 if align > 0 {
106 debug_assert!((align & (MIN_ALIGN - 1)) == 0);
107 debug_assert!((size as u32 & (align - 1)) == 0);
108 unsafe {
109 let res =
110 libc::posix_memalign(&mut ptr, align as libc::size_t, size as libc::size_t);
111 if res != 0 {
112 return Err(Errno::ENOMEM);
113 }
114 }
115 } else {
116 ptr = unsafe { libc::malloc(size as libc::size_t) };
117 if ptr == std::ptr::null_mut() {
118 return Err(Errno::ENOMEM);
119 }
120 }
121 let _size = size as u32 | MAX_BUFFER_SIZE as u32;
123 let _cap = _size;
125 Ok(Self { buf_ptr: ptr, size: _size, cap: _cap })
126 }
127
128 #[inline]
134 pub fn from_c_ref_mut(ptr: *mut libc::c_void, size: i32) -> Self {
135 assert!(size >= 0);
136 assert!(ptr != std::ptr::null_mut());
137 let _cap = size as u32 | MAX_BUFFER_SIZE as u32;
140 Self { buf_ptr: ptr, size: size as u32, cap: _cap }
141 }
142
143 #[inline]
149 pub fn from_c_ref_const(ptr: *const libc::c_void, size: i32) -> Self {
150 assert!(size >= 0);
151 assert!(ptr != std::ptr::null());
152 Self { buf_ptr: unsafe { std::mem::transmute(ptr) }, size: size as u32, cap: size as u32 }
155 }
156
157 #[inline(always)]
159 pub fn is_owned(&self) -> bool {
160 self.size & (MAX_BUFFER_SIZE as u32) != 0
161 }
162
163 #[inline(always)]
165 pub fn is_mutable(&self) -> bool {
166 self.cap & (MAX_BUFFER_SIZE as u32) != 0
167 }
168
169 #[inline(always)]
171 pub fn len(&self) -> usize {
172 let size = self.size & (MAX_BUFFER_SIZE as u32 - 1);
173 size as usize
174 }
175
176 #[inline(always)]
178 pub fn capacity(&self) -> usize {
179 let cap = self.cap & (MAX_BUFFER_SIZE as u32 - 1);
180 cap as usize
181 }
182
183 #[inline(always)]
185 pub fn set_len(&mut self, len: usize) {
186 assert!(len < MAX_BUFFER_SIZE, "size {} >= {} is not supported", len, MAX_BUFFER_SIZE);
187 assert!(len <= self.cap as usize, "size {} must be <= {}", len, self.cap);
188 let owned: u32 = self.size & MAX_BUFFER_SIZE as u32;
189 self.size = owned | len as u32;
190 }
191
192 #[inline(always)]
193 pub fn as_ref(&self) -> &[u8] {
194 unsafe { slice::from_raw_parts(self.buf_ptr as *const u8, self.len()) }
195 }
196
197 #[inline(always)]
201 pub fn as_mut(&mut self) -> &mut [u8] {
202 #[cfg(debug_assertions)]
203 {
204 if !self.is_mutable() {
205 panic!("Cannot change a mutable buffer")
206 }
207 }
208 unsafe { slice::from_raw_parts_mut(self.buf_ptr as *mut u8, self.len()) }
209 }
210
211 #[inline(always)]
213 pub fn is_aligned(&self) -> bool {
214 is_aligned(self.buf_ptr as usize, self.capacity())
215 }
216
217 #[inline]
219 pub fn get_raw(&self) -> *const u8 {
220 self.buf_ptr as *const u8
221 }
222
223 #[inline]
225 pub fn get_raw_mut(&mut self) -> *mut u8 {
226 self.buf_ptr as *mut u8
227 }
228
229 #[inline]
237 pub fn copy_from(&mut self, offset: usize, other: &[u8]) {
238 let size = self.len();
239 let dst = self.as_mut();
240 if offset > 0 {
241 assert!(offset < size);
242 safe_copy(&mut dst[offset..], other);
243 } else {
244 safe_copy(dst, other);
245 }
246 }
247
248 #[inline]
254 pub fn copy_and_clean(&mut self, offset: usize, other: &[u8]) {
255 let end: usize;
256 let size = self.len();
257 let dst = self.as_mut();
258 assert!(offset < size);
259 if offset > 0 {
260 set_zero(&mut dst[0..offset]);
261 end = offset + safe_copy(&mut dst[offset..], other);
262 } else {
263 end = safe_copy(dst, other);
264 }
265 if size > end {
266 set_zero(&mut dst[end..]);
267 }
268 }
269
270 #[inline]
272 pub fn zero(&mut self) {
273 set_zero(self);
274 }
275
276 #[inline]
278 pub fn set_zero(&mut self, offset: usize, len: usize) {
279 let _len = self.len();
280 let mut end = offset + len;
281 if end > _len {
282 end = _len;
283 }
284 let buf = self.as_mut();
285 if offset > 0 || end < _len {
286 set_zero(&mut buf[offset..end]);
287 } else {
288 set_zero(buf);
289 }
290 }
291}
292
293impl Clone for Buffer {
296 fn clone(&self) -> Self {
297 let mut new_buf = if self.is_aligned() {
298 Self::aligned(self.capacity() as i32).unwrap()
299 } else {
300 Self::alloc(self.capacity() as i32).unwrap()
301 };
302 if self.len() != self.capacity() {
303 new_buf.set_len(self.len());
304 }
305 safe_copy(new_buf.as_mut(), self.as_ref());
306 new_buf
307 }
308}
309
310impl Drop for Buffer {
312 fn drop(&mut self) {
313 if self.is_owned() {
314 unsafe {
315 libc::free(self.buf_ptr);
316 }
317 }
318 }
319}
320
321impl Into<Vec<u8>> for Buffer {
323 fn into(mut self) -> Vec<u8> {
324 if !self.is_owned() {
325 panic!("buffer is c ref, not owned");
326 }
327 self.size &= MAX_BUFFER_SIZE as u32 - 1;
329 return unsafe {
330 Vec::<u8>::from_raw_parts(self.buf_ptr as *mut u8, self.len(), self.capacity())
331 };
332 }
333}
334
335impl From<Vec<u8>> for Buffer {
337 fn from(buf: Vec<u8>) -> Self {
338 let size = buf.len();
339 let cap = buf.capacity();
340 assert!(size < MAX_BUFFER_SIZE, "size {} >= {} is not supported", size, MAX_BUFFER_SIZE);
341 assert!(cap < MAX_BUFFER_SIZE, "cap {} >= {} is not supported", cap, MAX_BUFFER_SIZE);
342 let _size = size as u32 | MAX_BUFFER_SIZE as u32;
344 let _cap = cap as u32 | MAX_BUFFER_SIZE as u32;
346 Buffer { buf_ptr: buf.leak().as_mut_ptr() as *mut libc::c_void, size: _size, cap: _cap }
347 }
348}
349
350impl Deref for Buffer {
351 type Target = [u8];
352
353 #[inline]
354 fn deref(&self) -> &[u8] {
355 self.as_ref()
356 }
357}
358
359impl AsRef<[u8]> for Buffer {
360 #[inline]
361 fn as_ref(&self) -> &[u8] {
362 self.as_ref()
363 }
364}
365
366impl AsMut<[u8]> for Buffer {
370 #[inline]
371 fn as_mut(&mut self) -> &mut [u8] {
372 self.as_mut()
373 }
374}
375
376impl DerefMut for Buffer {
377 #[inline]
378 fn deref_mut(&mut self) -> &mut [u8] {
379 self.as_mut()
380 }
381}