rumtk_core/buffers/
rumbuffer.rs1use crate::base::{RUMResult, RUMVec};
21use crate::buffers::buffer_to_str;
22use crate::mem::{as_slice_mut, copy_from_slice, AsPtr, AsSlice, SizedType};
23use rumtk_arena::dune::Dune;
24use rumtk_arena::rumtk_dune_new;
25use std::cmp::PartialEq;
26use std::mem;
27use std::ops::DerefMut;
28use std::ops::{Deref, RangeTo, RangeToInclusive};
29use std::ops::{Index, Range, RangeFull};
30use std::sync::LazyLock;
31
32#[derive(Default, Debug, Clone)]
33enum RUMBufferDataPtr {
34 StaticBuffer(&'static [u8]),
35 String(String),
36 Vec(RUMVec<u8>),
37 Arena(Dune),
38 #[default]
39 None
40}
41
42impl PartialEq for RUMBufferDataPtr {
43 fn eq(&self, other: &Self) -> bool {
44 mem::discriminant(self) == mem::discriminant(other)
45 }
46}
47
48pub type RUMBufferInner = RUMBufferDataPtr;
49
50const EMPTY_BUFFER_DATA: [u8;0] = [0;0];
51static EMPTY_RUMBUFFER: LazyLock<RUMBuffer> = LazyLock::new(|| RUMBuffer::new());
52
53#[derive(Debug)]
83pub struct RUMBuffer {
84 data: RUMBufferInner,
85 ptr: *const u8,
86 size: usize,
87}
88
89impl RUMBuffer {
90 #[inline]
91 pub const fn new() -> Self {
92 let data_length = 0;
93 let ptr = EMPTY_BUFFER_DATA.as_ptr();
94 Self {
95 data: RUMBufferDataPtr::None,
96 ptr,
97 size: data_length,
98 }
99 }
100
101 #[inline]
102 pub fn from_slice(data: &[u8]) -> Self {
103 if data.is_empty() {
104 return Self::new();
105 }
106
107 let data_length = data.len();
108 let mut mem = rumtk_dune_new!(data_length);
109 let mut ptr = mem.allocate_raw(data_length).unwrap();
110 let dst = as_slice_mut(ptr, data_length);
111 copy_from_slice(&data[..], dst);
112 Self {
113 data: RUMBufferDataPtr::Arena(mem),
114 ptr,
115 size: data_length,
116 }
117 }
118
119 #[inline]
120 pub fn from_vec(mut data: Vec<u8>) -> Self {
121 let mut ptr = data.as_mut_ptr();
122 let size = data.len();
123 Self {
124 data: RUMBufferDataPtr::Vec(data),
125 ptr,
126 size,
127 }
128 }
129
130 #[inline]
131 pub fn from_string(mut data: String) -> Self {
132 let mut ptr = data.as_mut_ptr();
133 let size = data.len();
134 Self {
135 data: RUMBufferDataPtr::String(data),
136 ptr,
137 size,
138 }
139 }
140
141 #[inline]
142 pub fn from_static(mut data: &'static [u8]) -> Self {
143 let mut ptr = data.as_mut_ptr();
144 let size = data.len();
145 Self {
146 data: RUMBufferDataPtr::StaticBuffer(data),
147 ptr,
148 size,
149 }
150 }
151
152 #[inline]
153 pub fn split_to(&mut self, offset: usize) -> Self {
154 debug_assert!(offset <= self.size, "offset too large");
155 let copy = Self {
156 data: RUMBufferDataPtr::None,
157 ptr: self.ptr,
158 size: offset,
159 };
160 self.ptr = unsafe { self.ptr.add(offset) };
161 self.size -= offset;
162 copy
163 }
164
165 #[inline]
166 pub fn freeze(&self) -> Self {
167 Self {
168 data: RUMBufferDataPtr::None,
169 ptr: self.ptr,
170 size: self.size,
171 }
172 }
173
174 #[inline]
175 pub fn to_vec(&self) -> RUMVec<u8> {
176 self.as_slice().to_vec()
177 }
178
179 #[inline]
180 pub fn as_str(&self) -> RUMResult<&str> {
181 buffer_to_str(self)
182 }
183
184 #[inline]
185 pub fn truncate(&mut self, len: usize) {
186 self.size = len;
187 }
188
189 #[inline]
190 pub fn is_empty(&self) -> bool {
191 self.size == 0
192 }
193
194 #[inline]
195 pub fn is_buffer(&self) -> bool {
196 !self.is_view()
197 }
198
199 #[inline]
200 pub fn is_view(&self) -> bool {
201 self.data == RUMBufferDataPtr::None
202 }
203}
204
205impl Iterator for RUMBuffer {
206 type Item = u8;
207
208 #[inline]
209 fn next(&mut self) -> Option<Self::Item> {
210 if self.size == 0 { return None };
211
212 let v = self[0];
213 self.ptr = unsafe { self.ptr.add(1) };
214 Some(v)
215 }
216}
217
218impl SizedType for RUMBuffer {
219 fn size(&self) -> usize {
220 self.size
221 }
222}
223
224impl AsPtr for RUMBuffer {
225 #[inline(always)]
226 fn as_ptr(&self) -> *const u8 {
227 self.ptr
228 }
229 #[inline(always)]
230 fn as_mut_ptr(&mut self) -> *mut u8 {
231 self.ptr as *mut u8
232 }
233}
234
235impl AsSlice for RUMBuffer { }
236
237impl AsRef<[u8]> for RUMBuffer {
238 #[inline]
239 fn as_ref(&self) -> &[u8] {
240 self.as_slice()
241 }
242}
243
244impl Deref for RUMBuffer {
245 type Target = [u8];
246 #[inline]
247 fn deref(&self) -> &Self::Target {
248 self.as_slice()
249 }
250}
251
252impl DerefMut for RUMBuffer {
253 #[inline]
254 fn deref_mut(&mut self) -> &mut [u8] {
255 self.as_slice_mut()
256 }
257}
258
259impl PartialEq for RUMBuffer {
260 #[inline]
261 fn eq(&self, other: &Self) -> bool {
262 self.as_slice() == other.as_slice()
263 }
264}
265
266impl Default for RUMBuffer {
267 #[inline]
268 fn default() -> Self {
269 Self::new()
270 }
271}
272
273impl Clone for RUMBuffer {
274 #[inline]
275 fn clone(&self) -> Self {
276 self.freeze()
277 }
278}
279
280unsafe impl Send for RUMBuffer {}
293unsafe impl Sync for RUMBuffer {}
294
295impl Index<usize> for RUMBuffer {
298 type Output = u8;
299 #[inline]
300 fn index(&self, i: usize) -> &Self::Output {
301 &self.as_slice()[i]
302 }
303}
304
305impl Index<Range<usize>> for RUMBuffer {
306 type Output = [u8];
307 #[inline]
308 fn index(&self, i: Range<usize>) -> &Self::Output {
309 &self.as_slice()[i.start..i.end]
310 }
311}
312
313impl Index<RangeTo<usize>> for RUMBuffer {
314 type Output = [u8];
315 #[inline]
316 fn index(&self, i: RangeTo<usize>) -> &Self::Output {
317 &self.as_slice()[..i.end]
318 }
319}
320
321impl Index<RangeToInclusive<usize>> for RUMBuffer {
322 type Output = [u8];
323 #[inline]
324 fn index(&self, i: RangeToInclusive<usize>) -> &Self::Output {
325 &self.as_slice()[..=i.end]
326 }
327}
328
329impl Index<RangeFull> for RUMBuffer {
330 type Output = [u8];
331 #[inline]
332 fn index(&self, i: RangeFull) -> &Self::Output {
333 self.as_slice()
334 }
335}
336
337impl From<String> for RUMBuffer {
339 #[inline]
340 fn from(data: String) -> Self {
341 Self::from_string(data)
342 }
343}
344impl From<Vec<u8>> for RUMBuffer {
345 #[inline]
346 fn from(data: Vec<u8>) -> Self {
347 Self::from_vec(data)
348 }
349}
350
351impl From<&RUMVec<u8>> for RUMBuffer {
352 #[inline]
353 fn from(data: &RUMVec<u8>) -> Self {
354 Self::from_slice(data.as_slice())
355 }
356}
357
358impl From<&[u8]> for RUMBuffer {
359 #[inline]
360 fn from(data: &[u8]) -> Self {
361 Self::from_slice(data)
362 }
363}
364
365impl<const N: usize> From<&[u8; N]> for RUMBuffer {
366 #[inline]
367 fn from(data: &[u8; N]) -> Self {
368 Self::from(data.as_slice())
369 }
370}
371
372impl From<&str> for RUMBuffer {
373 #[inline]
374 fn from(data: &str) -> Self {
375 Self::from(data.as_bytes())
376 }
377}