il2cpp_bridge_rs/structs/core/metadata/
image.rs1use crate::api::{self, cache};
3use crate::structs::core::Class;
4use std::ffi::c_void;
5
6use super::assembly::Assembly;
7
8#[derive(Debug, Clone)]
12pub struct Image {
13 pub address: *mut c_void,
15 pub name: String,
17 pub filename: String,
19 pub assembly: *mut c_void,
21 pub entry_point: *mut c_void,
23}
24
25unsafe impl Send for Image {}
26unsafe impl Sync for Image {}
27
28impl Image {
29 pub fn get_assembly(&self) -> Option<std::sync::Arc<Assembly>> {
31 unsafe {
32 let assembly_ptr = api::image_get_assembly(self.address);
33 if assembly_ptr.is_null() {
34 return None;
35 }
36
37 for entry in cache::CACHE.assemblies.iter() {
38 if entry.value().address == assembly_ptr {
39 return Some(std::sync::Arc::clone(entry.value()));
40 }
41 }
42 None
43 }
44 }
45
46 pub fn get_classes(&self) -> Vec<Class> {
48 let mut classes = Vec::new();
49 unsafe {
50 let class_count = api::image_get_class_count(self.address);
51 for i in 0..class_count {
52 let class_ptr = api::image_get_class(self.address, i);
53 if !class_ptr.is_null() {
54 if let Some(class) = cache::class_from_ptr(class_ptr) {
55 classes.push(class);
56 }
57 }
58 }
59 }
60 classes
61 }
62
63 pub fn class(&self, name: &str) -> Option<Class> {
69 if let Some(class) = cache::CACHE.classes.get(name) {
70 return Some((**class).clone());
71 }
72
73 let (namespace, class_name) = if let Some(idx) = name.rfind('.') {
74 (&name[..idx], &name[idx + 1..])
75 } else {
76 ("", name)
77 };
78
79 unsafe {
80 let ns_cstr = std::ffi::CString::new(namespace).ok()?;
81 let name_cstr = std::ffi::CString::new(class_name).ok()?;
82
83 let class_ptr =
84 api::class_from_name(self.address, ns_cstr.as_ptr(), name_cstr.as_ptr());
85
86 if !class_ptr.is_null() {
87 cache::class_from_ptr(class_ptr)
88 } else {
89 None
90 }
91 }
92 }
93}