commonlibsse_ng\re\b\BSTArray\allocator/
scrap.rs

1use 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}