commonlibsse_ng\re\b\BSTArray\allocator/
scrap.rs1use core::alloc::Layout;
2use core::ffi::c_void;
3use core::ptr::{NonNull, copy_nonoverlapping, null_mut};
4use std::alloc::handle_alloc_error;
5
6use super::Allocator;
7use crate::re::MemoryManager::alloc::scrap_alloc;
8use crate::re::ScrapHeap::ScrapHeap;
9
10#[derive(Debug)]
11pub struct BSScrapArrayAllocator {
12 allocator: Option<NonNull<ScrapHeap>>,
13 data: *mut c_void,
14 capacity: u32,
15}
16const _: () = assert!(core::mem::size_of::<BSScrapArrayAllocator>() == 0x18);
17
18unsafe impl Allocator for BSScrapArrayAllocator {
19 #[inline]
20 fn new() -> Self {
21 Self { allocator: None, data: null_mut(), capacity: 0 }
22 }
23
24 #[inline]
25 fn as_ptr(&self) -> *const c_void {
26 self.data.cast_const()
27 }
28
29 #[inline]
30 fn as_mut_ptr(&mut self) -> *mut c_void {
31 self.data
32 }
33
34 #[inline]
35 fn capacity(&self) -> u32 {
36 self.capacity
37 }
38
39 #[inline]
40 unsafe fn allocate(&mut self, layout: Layout) -> *mut c_void {
41 let Ok((scrap_heap, ptr)) = (match self.allocator {
42 Some(allocator) => unsafe { scrap_alloc::realloc(allocator, layout) },
43 None => unsafe { scrap_alloc::alloc_zeroed(layout) },
44 }) else {
45 handle_alloc_error(layout)
46 };
47 self.allocator = Some(scrap_heap);
48 ptr.cast().as_ptr()
49 }
50
51 #[inline]
52 unsafe fn deallocate(&mut self, ptr: *mut c_void) {
53 if let Some(allocator) = self.allocator.as_mut() {
54 if !ptr.is_null() {
55 unsafe { allocator.as_mut().deallocate(ptr) };
56 }
57 }
58 }
59
60 #[inline]
61 fn set_allocator_traits(&mut self, data: *mut c_void, capacity: u32, type_size: usize) {
62 let _ = type_size;
63 self.data = data;
64 self.capacity = capacity;
65 }
66}
67
68impl Default for BSScrapArrayAllocator {
69 #[inline]
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75impl Drop for BSScrapArrayAllocator {
76 fn drop(&mut self) {
77 unsafe { self.deallocate(self.data) };
78 }
79}
80
81impl Clone for BSScrapArrayAllocator {
82 #[inline]
83 fn clone(&self) -> Self {
84 let mut new_allocator = Self::new();
85 new_allocator.capacity = self.capacity;
86
87 if self.capacity > 0 {
88 unsafe {
89 const PTR_ALIGN_SIZE: usize = align_of::<*mut c_void>();
90 let layout = Layout::from_size_align(self.capacity as usize, PTR_ALIGN_SIZE)
91 .expect("Valid layout");
92 new_allocator.data = new_allocator.allocate(layout);
93 copy_nonoverlapping(self.data, new_allocator.data, self.capacity as usize);
94 }
95 }
96 new_allocator
97 }
98}