boot_services/
boxed.rs

1use alloc::slice;
2use core::{
3    mem,
4    ops::{Deref, DerefMut},
5    ptr,
6};
7
8use crate::{allocation::MemoryType, BootServices};
9
10#[derive(Debug)]
11pub struct BootServicesBox<'a, T: ?Sized, B: BootServices + ?Sized> {
12    ptr: *mut T,
13    boot_services: &'a B,
14}
15
16impl<'a, T, B: BootServices> BootServicesBox<'a, T, B> {
17    pub fn new(value: T, memory_type: MemoryType, boot_services: &'a B) -> Self {
18        let size = mem::size_of_val(&value);
19        let ptr = boot_services.allocate_pool(memory_type, size).unwrap() as *mut T;
20        unsafe { ptr::write(ptr, value) };
21        Self { boot_services, ptr }
22    }
23
24    pub unsafe fn from_raw(ptr: *mut T, boot_services: &'a B) -> Self {
25        Self { boot_services, ptr }
26    }
27
28    pub unsafe fn into_raw(self) -> *const T {
29        self.ptr as *const T
30    }
31
32    pub unsafe fn into_raw_mut(self) -> *mut T {
33        self.ptr
34    }
35
36    pub fn leak(self) -> &'a mut T {
37        let leak = unsafe { self.ptr.as_mut() }.unwrap();
38        mem::forget(self);
39        leak
40    }
41}
42
43impl<'a, T, B: BootServices> BootServicesBox<'a, [T], B> {
44    pub unsafe fn from_raw_parts_mut(ptr: *mut T, len: usize, boot_services: &'a B) -> Self {
45        let ptr = slice::from_raw_parts_mut(ptr, len) as *mut [T];
46        Self { boot_services, ptr }
47    }
48}
49
50impl<T: ?Sized, B: BootServices + ?Sized> Drop for BootServicesBox<'_, T, B> {
51    fn drop(&mut self) {
52        let _ = self.boot_services.free_pool(self.ptr as *mut u8);
53    }
54}
55
56impl<T: ?Sized, B: BootServices> Deref for BootServicesBox<'_, T, B> {
57    type Target = T;
58
59    fn deref(&self) -> &Self::Target {
60        unsafe { self.ptr.as_ref() }.unwrap()
61    }
62}
63
64impl<T: ?Sized, B: BootServices> DerefMut for BootServicesBox<'_, T, B> {
65    fn deref_mut(&mut self) -> &mut Self::Target {
66        unsafe { self.ptr.as_mut() }.unwrap()
67    }
68}
69
70impl<T: ?Sized, B: BootServices> AsRef<T> for BootServicesBox<'_, T, B> {
71    fn as_ref(&self) -> &T {
72        self.deref()
73    }
74}
75
76impl<T: ?Sized, B: BootServices> AsMut<T> for BootServicesBox<'_, T, B> {
77    fn as_mut(&mut self) -> &mut T {
78        self.deref_mut()
79    }
80}