1mod large;
2mod utils;
3use large::{BufferLarge, MIN_ALIGN};
4
5pub use utils::*;
6
7#[cfg(feature = "compress")]
8pub mod lz4;
9
10#[cfg(test)]
11mod test;
12
13use nix::errno::Errno;
14use std::{
15 fmt,
16 ops::{Deref, DerefMut},
17};
18
19use fail::fail_point;
20
21#[derive(Clone)]
25pub enum Buffer {
26 Large(BufferLarge),
27 Vec(Vec<u8>),
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
36impl Buffer {
37 #[inline]
41 pub fn aligned(size: usize) -> Result<Buffer, Errno> {
42 let mut _buf = BufferLarge::alloc(MIN_ALIGN, size)?;
43 fail_point!("alloc_buf", |_| {
44 rand_buffer(&mut _buf);
45 return Ok(Buffer::Large(_buf));
46 });
47 return Ok(Buffer::Large(_buf));
48 }
49
50 #[inline]
53 pub fn alloc(size: usize) -> Result<Buffer, Errno> {
54 let mut _buf = BufferLarge::alloc(0, size)?;
55 fail_point!("alloc_buf", |_| {
56 rand_buffer(&mut _buf);
57 return Ok(Buffer::Large(_buf));
58 });
59 return Ok(Buffer::Large(_buf));
60 }
61
62 #[inline]
66 pub fn from_c_ref_mut(ptr: *mut libc::c_void, size: usize) -> Self {
67 Self::Large(BufferLarge::from_c_ref_mut(ptr, size))
68 }
69
70 #[inline]
74 pub fn from_c_ref_const(ptr: *const libc::c_void, size: usize) -> Self {
75 Self::Large(BufferLarge::from_c_ref_const(ptr, size))
76 }
77
78 #[inline(always)]
79 pub fn len(&self) -> usize {
80 match self {
81 Buffer::Large(buf) => buf.size as usize,
82 Buffer::Vec(buf) => buf.len(),
83 }
84 }
85
86 #[inline]
88 pub fn get_raw(&self) -> *const u8 {
89 match self {
90 Buffer::Large(buf) => buf.buf_ptr as *const u8,
91 Buffer::Vec(buf) => buf.as_ptr(),
92 }
93 }
94
95 #[inline]
97 pub fn get_raw_mut(&mut self) -> *mut u8 {
98 match self {
99 Buffer::Large(buf) => buf.buf_ptr as *mut u8,
100 Buffer::Vec(v) => v.as_mut_ptr(),
101 }
102 }
103
104 #[inline]
112 pub fn copy_from(&mut self, offset: usize, other: &[u8]) {
113 let size = self.len();
114 let dst = self.as_mut();
115 if offset > 0 {
116 assert!(offset < size);
117 safe_copy(&mut dst[offset..], other);
118 } else {
119 safe_copy(dst, other);
120 }
121 }
122
123 #[inline]
129 pub fn copy_and_clean(&mut self, offset: usize, other: &[u8]) {
130 let end: usize;
131 let size = self.len();
132 let dst = self.as_mut();
133 assert!(offset < size);
134 if offset > 0 {
135 set_zero(&mut dst[0..offset]);
136 end = offset + safe_copy(&mut dst[offset..], other);
137 } else {
138 end = safe_copy(dst, other);
139 }
140 if size > end {
141 set_zero(&mut dst[end..]);
142 }
143 }
144
145 #[inline]
147 pub fn zero(&mut self) {
148 set_zero(self);
149 }
150
151 #[inline]
153 pub fn set_zero(&mut self, offset: usize, len: usize) {
154 let _len = self.len();
155 let mut end = offset + len;
156 if end > _len {
157 end = _len;
158 }
159 let buf = self.as_mut();
160 if offset > 0 || end < _len {
161 set_zero(&mut buf[offset..end]);
162 } else {
163 set_zero(buf);
164 }
165 }
166
167 #[inline]
168 pub fn is_aligned(&self) -> bool {
169 match self {
170 Buffer::Large(buf) => buf.is_aligned(),
171 Buffer::Vec(_) => false,
172 }
173 }
174}
175
176impl Into<Vec<u8>> for Buffer {
177 fn into(self) -> Vec<u8> {
178 if let Buffer::Vec(v) = self { v } else { unimplemented!() }
179 }
180}
181
182impl From<Vec<u8>> for Buffer {
183 fn from(buf: Vec<u8>) -> Self {
184 Buffer::Vec(buf)
185 }
186}
187
188impl Deref for Buffer {
189 type Target = [u8];
190
191 #[inline]
192 fn deref(&self) -> &[u8] {
193 match self {
194 Self::Large(buf) => buf.as_ref(),
195 Self::Vec(v) => &v,
196 }
197 }
198}
199
200impl AsRef<[u8]> for Buffer {
201 #[inline]
202 fn as_ref(&self) -> &[u8] {
203 match self {
204 Self::Large(buf) => buf.as_ref(),
205 Self::Vec(v) => v.as_ref(),
206 }
207 }
208}
209
210impl AsMut<[u8]> for Buffer {
211 #[inline]
212 fn as_mut(&mut self) -> &mut [u8] {
213 match self {
214 Self::Large(buf) => buf.as_mut(),
215 Self::Vec(v) => v.as_mut(),
216 }
217 }
218}
219
220impl DerefMut for Buffer {
221 #[inline]
222 fn deref_mut(&mut self) -> &mut [u8] {
223 match self {
224 Self::Large(buf) => buf.as_mut(),
225 Self::Vec(v) => v.as_mut(),
226 }
227 }
228}