1use glib::translate::{
22 from_glib_full, from_glib_none, FromGlibPtrFull, FromGlibPtrNone, StashMut, ToGlibPtr,
23 ToGlibPtrMut,
24};
25use libc::c_void;
26use std::ptr::{self, NonNull};
27
28#[doc(alias = "GITypelib")]
30#[derive(Debug)]
31pub struct Typelib(NonNull<ffi::GITypelib>);
32
33impl Typelib {
34 pub fn new_from_bytes(memory: &[u8]) -> Result<Self, glib::Error> {
35 unsafe {
36 let mut error = ptr::null_mut();
37 let rtrn =
38 ffi::g_typelib_new_from_const_memory(memory.as_ptr(), memory.len(), &mut error);
39 if error.is_null() {
40 Ok(from_glib_none(rtrn))
41 } else {
42 Err(from_glib_full(error))
43 }
44 }
45 }
46 pub fn new_from_mapped_file(mfile: *mut glib_sys::GMappedFile) -> Result<Self, glib::Error> {
47 unsafe {
48 let mut error = ptr::null_mut();
49 let rtrn = ffi::g_typelib_new_from_mapped_file(mfile, &mut error);
50 if error.is_null() {
51 Ok(from_glib_none(rtrn))
52 } else {
53 Err(from_glib_full(error))
54 }
55 }
56 }
57
58 pub fn namespace(&self) -> Option<glib::GString> {
59 unsafe { from_glib_none(ffi::g_typelib_get_namespace(self.0.as_ptr())) }
60 }
61 pub unsafe fn load_symbol(&self, symbol_name: &str) -> Option<*mut c_void> { let mut rtrn = std::ptr::null_mut();
63 if ffi::g_typelib_symbol(self.0.as_ptr(), symbol_name.to_glib_none().0, &mut rtrn) == 0 {
64 None
65 } else {
66 Some(rtrn);
67 todo!("dlopen symbol")
68 }
69 }
70
71 pub fn data(&self) -> &[u8] {
72 unsafe {
73 let mut offset = 0;
74 let data_ptr = *self.0.as_ptr() as *const u8;
75 offset += std::mem::size_of::<*const u8>();
76 let data_len = *((self.0.as_ptr() as usize + offset) as *const usize);
77
78 std::slice::from_raw_parts(data_ptr, data_len)
79 }
80 }
81}
82
83impl Drop for Typelib {
84 fn drop(&mut self) {
85 unsafe { ffi::g_typelib_free(self.0.as_ptr()) }
86 }
87}
88impl FromGlibPtrNone<*mut ffi::GITypelib> for Typelib {
89 unsafe fn from_glib_none(ptr: *mut ffi::GITypelib) -> Self {
90 Self(match NonNull::new(ptr) {
91 Some(ptr) => {
92 assert!(!ptr.as_ref().is_null());
93 ptr
94 }
95 None => panic!("dereferenced null"),
96 })
97 }
98}
99impl FromGlibPtrFull<*mut ffi::GITypelib> for Typelib {
100 unsafe fn from_glib_full(ptr: *mut ffi::GITypelib) -> Self {
101 Self(match NonNull::new(ptr) {
102 Some(ptr) => {
103 assert!(!ptr.as_ref().is_null());
104 ptr
105 }
106 None => panic!("dereferenced null"),
107 })
108 }
109}
110impl<'a> ToGlibPtrMut<'a, *mut ffi::GITypelib> for Typelib {
111 type Storage = &'a mut Self;
112
113 fn to_glib_none_mut(&'a mut self) -> StashMut<*mut ffi::GITypelib, Self> {
114 StashMut(self.0.as_ptr(), self)
115 }
116}