brotli_decompressor/ffi/
alloc_util.rs
1use core;
2#[cfg(feature="std")]
3use std;
4use ::alloc;
5use super::interface::{c_void, CAllocator};
6#[cfg(feature="std")]
7use std::vec::Vec;
8#[cfg(feature="std")]
9pub use std::boxed::Box;
10
11#[cfg(feature="std")]
12pub struct MemoryBlock<Ty:Sized+Default>(Box<[Ty]>);
13#[cfg(feature="std")]
14impl<Ty:Sized+Default> Default for MemoryBlock<Ty> {
15 fn default() -> Self {
16 MemoryBlock(Vec::<Ty>::new().into_boxed_slice())
17 }
18}
19#[cfg(feature="std")]
20impl<Ty:Sized+Default> alloc::SliceWrapper<Ty> for MemoryBlock<Ty> {
21 fn slice(&self) -> &[Ty] {
22 &self.0[..]
23 }
24}
25#[cfg(feature="std")]
26impl<Ty:Sized+Default> alloc::SliceWrapperMut<Ty> for MemoryBlock<Ty> {
27 fn slice_mut(&mut self) -> &mut [Ty] {
28 &mut self.0[..]
29 }
30}
31#[cfg(feature="std")]
32impl<Ty:Sized+Default> core::ops::Index<usize> for MemoryBlock<Ty> {
33 type Output = Ty;
34 fn index(&self, index:usize) -> &Ty {
35 &self.0[index]
36 }
37}
38#[cfg(feature="std")]
39impl<Ty:Sized+Default> core::ops::IndexMut<usize> for MemoryBlock<Ty> {
40
41 fn index_mut(&mut self, index:usize) -> &mut Ty {
42 &mut self.0[index]
43 }
44}
45#[cfg(feature="std")]
46impl<Ty:Sized+Default> Drop for MemoryBlock<Ty> {
47 fn drop (&mut self) {
48 if self.0.len() != 0 {
49 print!("leaking memory block of length {} element size: {}\n", self.0.len(), core::mem::size_of::<Ty>());
50
51 let to_forget = core::mem::replace(self, MemoryBlock::default());
52 core::mem::forget(to_forget);}
54 }
55}
56pub struct SubclassableAllocator {
57 alloc: CAllocator
58 }
60
61impl SubclassableAllocator {
62 pub unsafe fn new(sub_alloc:CAllocator) -> Self {
63 SubclassableAllocator{
64 alloc:sub_alloc,
65 }
66 }
67}
68#[cfg(feature="std")]
69impl<Ty:Sized+Default+Clone> alloc::Allocator<Ty> for SubclassableAllocator {
70 type AllocatedMemory = MemoryBlock<Ty>;
71 fn alloc_cell(&mut self, size:usize) ->MemoryBlock<Ty>{
72 if size == 0 {
73 return MemoryBlock::<Ty>::default();
74 }
75 if let Some(alloc_fn) = self.alloc.alloc_func {
76 let ptr = alloc_fn(self.alloc.opaque, size * core::mem::size_of::<Ty>());
77 let typed_ptr = unsafe {core::mem::transmute::<*mut c_void, *mut Ty>(ptr)};
78 let slice_ref = unsafe {super::slice_from_raw_parts_or_nil_mut(typed_ptr, size)};
79 for item in slice_ref.iter_mut() {
80 unsafe{core::ptr::write(item, Ty::default())};
81 }
82 return MemoryBlock(unsafe{Box::from_raw(slice_ref)})
83 }
84 MemoryBlock(vec![Ty::default();size].into_boxed_slice())
85 }
86 fn free_cell(&mut self, mut bv:MemoryBlock<Ty>) {
87 if (*bv.0).len() != 0 {
88 if let Some(_) = self.alloc.alloc_func {
89 let slice_ptr = (*bv.0).as_mut_ptr();
90 let _box_ptr = Box::into_raw(core::mem::replace(&mut bv.0, Vec::<Ty>::new().into_boxed_slice()));
91 if let Some(free_fn) = self.alloc.free_func {
92 unsafe {free_fn(self.alloc.opaque, core::mem::transmute::<*mut Ty, *mut c_void>(slice_ptr))};
93 }
94 } else {
95 let _to_free = core::mem::replace(&mut bv.0, Vec::<Ty>::new().into_boxed_slice());
96 }
97 }
98 }
99}
100
101
102
103
104
105
106
107
108
109
110
111#[cfg(not(feature="std"))]
112static mut G_SLICE:&'static mut[u8] = &mut[];
113#[cfg(not(feature="std"))]
114pub struct MemoryBlock<Ty:Sized+Default>(*mut[Ty]);
115#[cfg(not(feature="std"))]
116impl<Ty:Sized+Default> Default for MemoryBlock<Ty> {
117 fn default() -> Self {
118 MemoryBlock(unsafe{core::mem::transmute::<*mut [u8], *mut[Ty]>(G_SLICE.as_mut())})
119 }
120}
121#[cfg(not(feature="std"))]
122impl<Ty:Sized+Default> alloc::SliceWrapper<Ty> for MemoryBlock<Ty> {
123 fn slice(&self) -> &[Ty] {
124 if unsafe{(*self.0).len()} == 0 {
125 &[]
126 } else {
127 unsafe{super::slice_from_raw_parts_or_nil(&(*self.0)[0], (*self.0).len())}
128 }
129 }
130}
131#[cfg(not(feature="std"))]
132impl<Ty:Sized+Default> alloc::SliceWrapperMut<Ty> for MemoryBlock<Ty> {
133 fn slice_mut(&mut self) -> &mut [Ty] {
134 if unsafe{(*self.0).len()} == 0 {
135 &mut []
136 } else {
137 unsafe{super::slice_from_raw_parts_or_nil_mut(&mut (*self.0)[0], (*self.0).len())}
138 }
139 }
140}
141
142#[cfg(not(feature="std"))]
143#[cfg(feature="no-stdlib-ffi-binding")]
144#[panic_handler]
145extern fn panic_impl(_: &::core::panic::PanicInfo) -> ! {
146 loop {}
147}
148#[cfg(not(feature="std"))]
149#[cfg(feature="no-stdlib-ffi-binding")]
150#[lang = "eh_personality"]
151extern "C" fn eh_personality() {
152}
153
154#[cfg(not(feature="std"))]
155impl<Ty:Sized+Default> core::ops::Index<usize> for MemoryBlock<Ty> {
156 type Output = Ty;
157 fn index(&self, index:usize) -> &Ty {
158 unsafe{&(*self.0)[index]}
159 }
160}
161#[cfg(not(feature="std"))]
162impl<Ty:Sized+Default> core::ops::IndexMut<usize> for MemoryBlock<Ty> {
163
164 fn index_mut(&mut self, index:usize) -> &mut Ty {
165 unsafe{&mut (*self.0)[index]}
166 }
167}
168
169#[cfg(not(feature="std"))]
170impl<Ty:Sized+Default+Clone> alloc::Allocator<Ty> for SubclassableAllocator {
171 type AllocatedMemory = MemoryBlock<Ty>;
172 fn alloc_cell(&mut self, size:usize) ->MemoryBlock<Ty>{
173 if size == 0 {
174 return MemoryBlock::<Ty>::default();
175 }
176 if let Some(alloc_fn) = self.alloc.alloc_func {
177 let ptr = alloc_fn(self.alloc.opaque, size * core::mem::size_of::<Ty>());
178 let typed_ptr = unsafe {core::mem::transmute::<*mut c_void, *mut Ty>(ptr)};
179 let slice_ref = unsafe {super::slice_from_raw_parts_or_nil_mut(typed_ptr, size)};
180 for item in slice_ref.iter_mut() {
181 unsafe{core::ptr::write(item, Ty::default())};
182 }
183 return MemoryBlock(slice_ref.as_mut())
184 } else {
185 panic!("Must provide allocators in no-stdlib code");
186 }
187 }
188 fn free_cell(&mut self, mut bv:MemoryBlock<Ty>) {
189 use alloc::SliceWrapper;
190 use alloc::SliceWrapperMut;
191 if bv.slice().len() != 0 {
192 if let Some(_) = self.alloc.alloc_func {
193 if let Some(free_fn) = self.alloc.free_func {
194 unsafe {free_fn(self.alloc.opaque, core::mem::transmute::<*mut Ty, *mut c_void>(&mut bv.slice_mut()[0]))};
195 }
196 let _ = core::mem::replace(&mut bv,
197 MemoryBlock::<Ty>::default());
198 } else {
199 panic!("Must provide allocators in no-stdlib code");
200 }
201 }
202 }
203}
204
205
206#[cfg(not(feature="std"))]
207pub fn free_stdlib<T>(_data: *mut T, _size: usize) {
208 panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
209}
210#[cfg(not(feature="std"))]
211pub fn alloc_stdlib<T:Sized+Default+Copy+Clone>(_size: usize) -> *mut T {
212 panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
213}
214
215#[cfg(feature="std")]
216pub unsafe fn free_stdlib<T>(ptr: *mut T, size: usize) {
217 let slice_ref = super::slice_from_raw_parts_or_nil_mut(ptr, size);
218 let _ = Box::from_raw(slice_ref); }
220#[cfg(feature="std")]
221pub fn alloc_stdlib<T:Sized+Default+Copy+Clone>(size: usize) -> *mut T {
222 std::panic::catch_unwind(|| {
223 let mut newly_allocated = vec![T::default();size].into_boxed_slice();
224 let slice_ptr = newly_allocated.as_mut_ptr();
225 let _box_ptr = Box::into_raw(newly_allocated);
226 slice_ptr
227 }).unwrap_or(core::ptr::null_mut())
228}