rumtk_arena/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 crate::rumtk_mem_layout;
24use std::alloc::{alloc, dealloc, Layout};
25use std::cmp::PartialEq;
26use std::ops::DerefMut;
27use std::ops::IndexMut;
28use std::ops::{Deref, RangeTo, RangeToInclusive};
29use std::ops::{Index, Range, RangeFull};
30use std::sync::LazyLock;
31
32const EMPTY_BUFFER_DATA: [u8;0] = [0;0];
33static EMPTY_RUMBUFFER: LazyLock<RUMBuffer> = LazyLock::new(|| RUMBuffer::new());
34
35#[derive(Debug)]
65pub struct RUMBuffer {
66 data: *const u8,
67 size: u32,
68 dealloc: bool,
69}
70
71impl RUMBuffer {
72 #[inline]
73 pub const fn new() -> Self {
74 Self {
75 data: EMPTY_BUFFER_DATA.as_ptr(),
76 size: 0,
77 dealloc: false,
78 }
79 }
80
81 #[inline]
82 pub fn from_slice(data: &[u8]) -> Self {
83 if data.is_empty() {
84 return Self::new();
85 }
86
87 let data_length = data.len();
88 let ptr = unsafe { alloc(Layout::from_size_align_unchecked(data_length, size_of::<u8>())) };
89 let dst = as_slice_mut(ptr, data_length);
90 copy_from_slice(&data[..], dst);
91 Self {
92 data: ptr,
93 size: data_length as u32,
94 dealloc: true,
95 }
96 }
97
98 #[inline]
99 pub fn from_static(mut data: &'static [u8]) -> Self {
100 let ptr = data.as_ptr();
101 let size = data.len();
102 Self {
103 data: ptr,
104 size: size as u32,
105 dealloc: false,
106 }
107 }
108
109 #[inline]
110 pub fn from_parts(data: *const u8, length: usize, dealloc: bool) -> Self {
111 Self {
112 data,
113 size: length as u32,
114 dealloc,
115 }
116 }
117
118 #[inline]
119 pub fn split_to(&mut self, offset: usize) -> Option<Self> {
120 if offset <= self.size as usize {
121 let ptr = self.as_ptr();
122 let new_ptr = unsafe { ptr.add(offset) };
123 let copy = Self {
124 data: ptr,
125 size: offset as u32,
126 dealloc: false,
127 };
128 self.data = new_ptr;
129 self.size -= (offset as u32);
130 Some(copy)
131 } else {
132 None
133 }
134 }
135
136 #[inline]
137 pub fn freeze(&self) -> Self {
138 Self {
139 data: self.as_ptr(),
140 size: self.size,
141 dealloc: false,
142 }
143 }
144
145 #[inline]
146 pub fn to_vec(&self) -> RUMVec<u8> {
147 self.as_slice().to_vec()
148 }
149
150 #[inline]
151 pub fn as_str(&self) -> RUMResult<&str> {
152 buffer_to_str(self)
153 }
154
155 #[inline]
156 pub fn truncate(&mut self, len: usize) {
157 self.size = len as u32;
158 }
159
160 #[inline]
161 pub fn is_empty(&self) -> bool {
162 self.size == 0
163 }
164
165 #[inline]
166 pub fn is_buffer(&self) -> bool {
167 self.dealloc
168 }
169
170 #[inline]
171 pub fn is_view(&self) -> bool {
172 !self.dealloc
173 }
174}
175
176impl Iterator for RUMBuffer {
177 type Item = u8;
178
179 #[inline]
180 fn next(&mut self) -> Option<Self::Item> {
181 if self.size == 0 { return None };
182
183 let v = self[0];
184 self.data = unsafe { self.as_ptr().add(1) };
185 Some(v)
186 }
187}
188
189impl SizedType for RUMBuffer {
190 fn size(&self) -> usize {
191 self.size as usize
192 }
193}
194
195impl AsPtr for RUMBuffer {
196 #[inline(always)]
197 fn as_ptr(&self) -> *const u8 {
198 self.data
199 }
200 #[inline(always)]
201 fn as_mut_ptr(&mut self) -> *mut u8 {
202 self.data as *mut u8
203 }
204}
205
206impl AsSlice for RUMBuffer { }
207
208impl AsRef<[u8]> for RUMBuffer {
209 #[inline]
210 fn as_ref(&self) -> &[u8] {
211 self.as_slice()
212 }
213}
214
215impl Deref for RUMBuffer {
216 type Target = [u8];
217 #[inline]
218 fn deref(&self) -> &Self::Target {
219 self.as_slice()
220 }
221}
222
223impl DerefMut for RUMBuffer {
224 #[inline]
225 fn deref_mut(&mut self) -> &mut [u8] {
226 self.as_slice_mut()
227 }
228}
229
230impl PartialEq for RUMBuffer {
231 #[inline]
232 fn eq(&self, other: &Self) -> bool {
233 self.as_slice() == other.as_slice()
234 }
235}
236
237impl Default for RUMBuffer {
238 #[inline]
239 fn default() -> Self {
240 Self::new()
241 }
242}
243
244impl Clone for RUMBuffer {
245 #[inline]
246 fn clone(&self) -> Self {
247 self.freeze()
248 }
249}
250
251impl Drop for RUMBuffer {
252 #[inline]
253 fn drop(&mut self) {
254 if self.dealloc {
255 unsafe {
256 dealloc(self.as_mut_ptr(), rumtk_mem_layout!(self.size as usize))
257 }
258 }
259 }
260}
261
262unsafe impl Send for RUMBuffer {}
263unsafe impl Sync for RUMBuffer {}
264
265impl Index<usize> for RUMBuffer {
268 type Output = u8;
269 #[inline]
270 fn index(&self, i: usize) -> &Self::Output {
271 &self.as_slice()[i]
272 }
273}
274
275impl Index<Range<usize>> for RUMBuffer {
276 type Output = [u8];
277 #[inline]
278 fn index(&self, i: Range<usize>) -> &Self::Output {
279 &self.as_slice()[i.start..i.end]
280 }
281}
282
283impl Index<RangeTo<usize>> for RUMBuffer {
284 type Output = [u8];
285 #[inline]
286 fn index(&self, i: RangeTo<usize>) -> &Self::Output {
287 &self.as_slice()[..i.end]
288 }
289}
290
291impl Index<RangeToInclusive<usize>> for RUMBuffer {
292 type Output = [u8];
293 #[inline]
294 fn index(&self, i: RangeToInclusive<usize>) -> &Self::Output {
295 &self.as_slice()[..=i.end]
296 }
297}
298
299impl Index<RangeFull> for RUMBuffer {
300 type Output = [u8];
301 #[inline]
302 fn index(&self, i: RangeFull) -> &Self::Output {
303 self.as_slice()
304 }
305}
306
307impl IndexMut<usize> for RUMBuffer {
310 #[inline]
311 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
312 &mut self.as_slice_mut()[i]
313 }
314}
315
316impl IndexMut<Range<usize>> for RUMBuffer {
317 #[inline]
318 fn index_mut(&mut self, i: Range<usize>) -> &mut Self::Output {
319 &mut self.as_slice_mut()[i.start..i.end]
320 }
321}
322
323impl IndexMut<RangeTo<usize>> for RUMBuffer {
324 #[inline]
325 fn index_mut(&mut self, i: RangeTo<usize>) -> &mut Self::Output {
326 &mut self.as_slice_mut()[..i.end]
327 }
328}
329
330impl IndexMut<RangeToInclusive<usize>> for RUMBuffer {
331 #[inline]
332 fn index_mut(&mut self, i: RangeToInclusive<usize>) -> &mut Self::Output {
333 &mut self.as_slice_mut()[..=i.end]
334 }
335}
336
337impl IndexMut<RangeFull> for RUMBuffer {
338 #[inline]
339 fn index_mut(&mut self, i: RangeFull) -> &mut Self::Output {
340 self.as_slice_mut()
341 }
342}
343
344impl From<String> for RUMBuffer {
346 #[inline]
347 fn from(mut data: String) -> Self {
348 let (s, l, c) = data.into_raw_parts();
349 Self::from_parts(s, l, true)
350 }
351}
352impl From<Vec<u8>> for RUMBuffer {
353 #[inline]
354 fn from(mut data: Vec<u8>) -> Self {
355 let (s, l, c) = data.into_raw_parts();
356 Self::from_parts(s, l, true)
357 }
358}
359
360impl From<&RUMVec<u8>> for RUMBuffer {
361 #[inline]
362 fn from(data: &RUMVec<u8>) -> Self {
363 Self::from_slice(data.as_slice())
364 }
365}
366
367impl From<&[u8]> for RUMBuffer {
368 #[inline]
369 fn from(data: &[u8]) -> Self {
370 Self::from_slice(data)
371 }
372}
373
374impl<const N: usize> From<&[u8; N]> for RUMBuffer {
375 #[inline]
376 fn from(data: &[u8; N]) -> Self {
377 Self::from(data.as_slice())
378 }
379}
380
381impl From<&str> for RUMBuffer {
382 #[inline]
383 fn from(data: &str) -> Self {
384 Self::from(data.as_bytes())
385 }
386}