1mod large;
2pub mod utils;
3use large::{BufferLarge, MIN_ALIGN};
4use utils::*;
5
6#[cfg(test)]
7mod test;
8
9use nix::errno::Errno;
10use std::{
11 fmt,
12 ops::{Deref, DerefMut},
13};
14
15use fail::fail_point;
16
17#[derive(Clone)]
21pub enum Buffer {
22 Large(BufferLarge),
23 Vec(Vec<u8>),
24}
25
26impl fmt::Debug for Buffer {
27 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28 write!(f, "buffer {:p} size {}", self.get_raw(), self.len())
29 }
30}
31
32impl Buffer {
33 #[inline]
36 pub fn aligned(size: usize) -> Result<Buffer, Errno> {
37 let mut _buf = BufferLarge::alloc(MIN_ALIGN, size)?;
38 fail_point!("alloc_buf", |_| {
39 rand_buffer(&mut _buf);
40 return Ok(Buffer::Large(_buf));
41 });
42 return Ok(Buffer::Large(_buf));
43 }
44
45 #[inline]
48 pub fn alloc(size: usize) -> Result<Buffer, Errno> {
49 let mut _buf = BufferLarge::alloc(0, size)?;
50 fail_point!("alloc_buf", |_| {
51 rand_buffer(&mut _buf);
52 return Ok(Buffer::Large(_buf));
53 });
54 return Ok(Buffer::Large(_buf));
55 }
56
57 #[inline]
60 pub fn from_c_ref_mut(ptr: *mut libc::c_void, size: usize) -> Self {
61 Self::Large(BufferLarge::from_c_ref_mut(ptr, size))
62 }
63
64 #[inline]
67 pub fn from_c_ref_const(ptr: *const libc::c_void, size: usize) -> Self {
68 Self::Large(BufferLarge::from_c_ref_const(ptr, size))
69 }
70
71 #[inline(always)]
72 pub fn len(&self) -> usize {
73 match self {
74 Buffer::Large(buf) => buf.size as usize,
75 Buffer::Vec(buf) => buf.len(),
76 }
77 }
78
79 #[inline]
81 pub fn get_raw(&self) -> *const u8 {
82 match self {
83 Buffer::Large(buf) => buf.buf_ptr as *const u8,
84 Buffer::Vec(buf) => buf.as_ptr(),
85 }
86 }
87
88 #[inline]
90 pub fn get_raw_mut(&mut self) -> *mut u8 {
91 match self {
92 Buffer::Large(buf) => buf.buf_ptr as *mut u8,
93 Buffer::Vec(v) => v.as_mut_ptr(),
94 }
95 }
96
97 #[inline]
101 pub fn copy_from(&mut self, offset: usize, other: &[u8]) {
102 let size = self.len();
103 let dst = self.as_mut();
104 if offset > 0 {
105 assert!(offset < size);
106 safe_copy(&mut dst[offset..], other);
107 } else {
108 safe_copy(dst, other);
109 }
110 }
111
112 #[inline]
116 pub fn copy_and_clean(&mut self, offset: usize, other: &[u8]) {
117 let end: usize;
118 let size = self.len();
119 let dst = self.as_mut();
120 assert!(offset < size);
121 if offset > 0 {
122 set_zero(&mut dst[0..offset]);
123 end = offset + safe_copy(&mut dst[offset..], other);
124 } else {
125 end = safe_copy(dst, other);
126 }
127 if size > end {
128 set_zero(&mut dst[end..]);
129 }
130 }
131
132 #[inline]
134 pub fn zero(&mut self) {
135 set_zero(self);
136 }
137
138 #[inline]
140 pub fn set_zero(&mut self, offset: usize, len: usize) {
141 let _len = self.len();
142 let mut end = offset + len;
143 if end > _len {
144 end = _len;
145 }
146 let buf = self.as_mut();
147 if offset > 0 || end < _len {
148 set_zero(&mut buf[offset..end]);
149 } else {
150 set_zero(buf);
151 }
152 }
153
154 #[inline]
155 pub fn is_aligned(&self) -> bool {
156 match self {
157 Buffer::Large(buf) => buf.is_aligned(),
158 Buffer::Vec(_) => false,
159 }
160 }
161}
162
163impl Into<Vec<u8>> for Buffer {
164 fn into(self) -> Vec<u8> {
165 if let Buffer::Vec(v) = self {
166 v
167 } else {
168 unimplemented!()
169 }
170 }
171}
172
173impl From<Vec<u8>> for Buffer {
174 fn from(buf: Vec<u8>) -> Self {
175 Buffer::Vec(buf)
176 }
177}
178
179impl Deref for Buffer {
180 type Target = [u8];
181
182 #[inline]
183 fn deref(&self) -> &[u8] {
184 match self {
185 Self::Large(buf) => buf.as_ref(),
186 Self::Vec(v) => &v,
187 }
188 }
189}
190
191impl AsMut<[u8]> for Buffer {
192 #[inline]
193 fn as_mut(&mut self) -> &mut [u8] {
194 match self {
195 Self::Large(buf) => buf.as_mut(),
196 Self::Vec(v) => v.as_mut(),
197 }
198 }
199}
200
201impl DerefMut for Buffer {
202 #[inline]
203 fn deref_mut(&mut self) -> &mut [u8] {
204 match self {
205 Self::Large(buf) => buf.as_mut(),
206 Self::Vec(v) => v.as_mut(),
207 }
208 }
209}