draco_oxide_core/buffer/
mod.rs1use crate::safety_assert;
2pub mod attribute;
3use std::{alloc, fmt, ptr};
7
8pub trait OrderConfig {
9 const IS_MSB_FIRST: bool;
10}
11
12#[derive(Debug)]
13pub struct MsbFirst;
14
15#[derive(Debug)]
16pub struct LsbFirst;
17
18impl OrderConfig for MsbFirst {
19 const IS_MSB_FIRST: bool = true;
20}
21impl OrderConfig for LsbFirst {
22 const IS_MSB_FIRST: bool = false;
23}
24
25pub struct Buffer<Order: OrderConfig = MsbFirst> {
26 data: RawBuffer,
27
28 len: usize,
31
32 _phantom: std::marker::PhantomData<Order>,
33}
34
35#[allow(dead_code)]
36impl<Order: OrderConfig> Buffer<Order> {
37 pub fn new() -> Self {
39 Self {
40 data: RawBuffer::new(),
41 len: 0,
42 _phantom: std::marker::PhantomData,
43 }
44 }
45
46 pub fn with_len(len: usize) -> Self {
48 let cap = (len + 7) >> 3;
49 let data = RawBuffer::with_capacity(cap);
50 Self {
51 data,
52 len,
53 _phantom: std::marker::PhantomData,
54 }
55 }
56
57 pub fn len(&self) -> usize {
59 self.len
60 }
61
62 pub fn as_slice(&self) -> &[u8] {
64 unsafe { std::slice::from_raw_parts(self.data.as_ptr(), (self.len + 7) >> 3) }
66 }
67}
68
69impl fmt::Debug for Buffer<MsbFirst> {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 for n in 0..(self.len + 7) >> 3 {
72 write!(f, "{:02x} ", unsafe { *self.data.as_ptr().add(n) })?;
73 }
74 write!(f, "len: {}", self.len)?;
75 Ok(())
76 }
77}
78
79struct RawBuffer {
80 data: ptr::NonNull<u8>,
81
82 cap: usize,
85}
86
87impl RawBuffer {
88 fn new() -> Self {
89 Self {
90 data: ptr::NonNull::dangling(),
91 cap: 0,
92 }
93 }
94
95 fn with_capacity(cap: usize) -> Self {
98 let data = unsafe { alloc::alloc(alloc::Layout::array::<u8>(cap).unwrap()) };
99 Self {
100 data: ptr::NonNull::new(data).unwrap(),
101 cap,
102 }
103 }
104
105 unsafe fn expand(&mut self, new_cap: usize) {
108 safety_assert!(new_cap < usize::MAX, "'new_cap' is too large");
109 let new_data = alloc::realloc(
110 self.data.as_ptr() as *mut u8,
111 alloc::Layout::array::<u8>(self.cap).unwrap(),
112 new_cap,
113 );
114 self.data = ptr::NonNull::new(new_data).unwrap_or_else(|| {
115 alloc::handle_alloc_error(alloc::Layout::array::<u8>(new_cap).unwrap())
116 });
117 self.cap = new_cap;
118 }
119
120 fn double(&mut self) {
122 let new_cap = self.cap * 2;
123 assert!(new_cap < usize::MAX, "'new_cap' is too large");
124 unsafe {
126 self.expand(new_cap);
127 }
128 }
129
130 fn as_ptr(&self) -> *mut u8 {
131 self.data.as_ptr()
132 }
133
134 fn from_vec<Data>(v: Vec<Data>) -> Self {
135 let cap = v.len() * std::mem::size_of::<Data>();
136 let data = v.as_ptr() as *mut u8;
137 std::mem::forget(v);
139 Self {
140 data: ptr::NonNull::new(data).unwrap(),
141 cap,
142 }
143 }
144}
145
146impl fmt::Debug for RawBuffer {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 for n in 0..self.cap {
149 write!(f, "{:02x} ", unsafe { *self.data.as_ptr().add(n) })?;
150 }
151 Ok(())
152 }
153}