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}