fromsoftware_shared/
unknown_pointer.rs1use std::{ffi::c_void, fmt};
2
3use crate::{Program, vftable_classname};
4
5#[repr(transparent)]
13#[derive(Clone, Copy)]
14pub struct UnknownPtr(*const c_void);
15
16impl UnknownPtr {
17 pub unsafe fn from(value: usize) -> Self {
24 UnknownPtr(value as *const c_void)
25 }
26
27 pub fn rtti_classname(&self) -> Option<String> {
30 if self.0.is_null() {
31 return None;
32 }
33
34 let usize_ptr = self.cast::<usize>();
35 if !usize_ptr.is_aligned() {
36 return None;
37 }
38
39 vftable_classname(&Program::current(), unsafe { *usize_ptr })
43 }
44
45 pub fn is_null(&self) -> bool {
47 self.0.is_null()
48 }
49
50 pub fn cast<T>(self) -> *const T {
52 self.0.cast::<T>()
53 }
54
55 pub fn addr(self) -> usize {
57 self.0.addr()
58 }
59}
60
61impl fmt::Debug for UnknownPtr {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
63 if let Some(name) = self.rtti_classname() {
64 write!(f, "{:?} [{name}*]", self.0)
65 } else {
66 fmt::Debug::fmt(&self.0, f)
67 }
68 }
69}
70
71impl fmt::Pointer for UnknownPtr {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
73 if let Some(name) = self.rtti_classname() {
74 write!(f, "{:p} [{name}*]", self.0)
75 } else {
76 fmt::Pointer::fmt(&self.0, f)
77 }
78 }
79}