std/sys/platform_version/darwin/
core_foundation.rs1#![allow(non_snake_case, non_upper_case_globals)]
3use super::root_relative;
4use crate::ffi::{CStr, c_char, c_void};
5use crate::ptr::null_mut;
6use crate::sys::helpers::run_path_with_cstr;
7
8pub(super) type Boolean = u8;
10pub(super) type CFTypeID = usize;
12pub(super) type CFOptionFlags = usize;
13pub(super) type CFIndex = isize;
14pub(super) type CFTypeRef = *mut c_void;
15pub(super) type CFAllocatorRef = CFTypeRef;
16pub(super) const kCFAllocatorDefault: CFAllocatorRef = null_mut();
17pub(super) type CFErrorRef = CFTypeRef;
19pub(super) type CFDataRef = CFTypeRef;
21pub(super) const kCFPropertyListImmutable: CFOptionFlags = 0;
23pub(super) type CFPropertyListFormat = CFIndex;
24pub(super) type CFPropertyListRef = CFTypeRef;
25pub(super) type CFStringRef = CFTypeRef;
27pub(super) type CFStringEncoding = u32;
28pub(super) const kCFStringEncodingUTF8: CFStringEncoding = 0x08000100;
29pub(super) type CFDictionaryRef = CFTypeRef;
31
32pub(super) struct CFHandle(*mut c_void);
41
42macro_rules! dlsym_fn {
43 (
44 unsafe fn $name:ident($($param:ident: $param_ty:ty),* $(,)?) $(-> $ret:ty)?;
45 ) => {
46 pub(super) unsafe fn $name(&self, $($param: $param_ty),*) $(-> $ret)? {
47 let ptr = unsafe {
48 libc::dlsym(
49 self.0,
50 concat!(stringify!($name), '\0').as_bytes().as_ptr().cast(),
51 )
52 };
53 if ptr.is_null() {
54 let err = unsafe { CStr::from_ptr(libc::dlerror()) };
55 panic!("could not find function {}: {err:?}", stringify!($name));
56 }
57
58 let fnptr = unsafe {
61 crate::mem::transmute::<
62 *mut c_void,
63 unsafe extern "C" fn($($param_ty),*) $(-> $ret)?,
64 >(ptr)
65 };
66
67 unsafe { fnptr($($param),*) }
69 }
70 };
71}
72
73impl CFHandle {
74 pub(super) fn new() -> Self {
76 let cf_path =
78 root_relative("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation");
79
80 let handle = run_path_with_cstr(&cf_path, &|path| unsafe {
81 Ok(libc::dlopen(path.as_ptr(), libc::RTLD_LAZY | libc::RTLD_LOCAL))
82 })
83 .expect("failed allocating string");
84
85 if handle.is_null() {
86 let err = unsafe { CStr::from_ptr(libc::dlerror()) };
87 panic!("could not open CoreFoundation.framework: {err:?}");
88 }
89
90 Self(handle)
91 }
92
93 pub(super) fn kCFAllocatorNull(&self) -> CFAllocatorRef {
94 let static_ptr = unsafe { libc::dlsym(self.0, c"kCFAllocatorNull".as_ptr()) };
96 if static_ptr.is_null() {
97 let err = unsafe { CStr::from_ptr(libc::dlerror()) };
98 panic!("could not find kCFAllocatorNull: {err:?}");
99 }
100 unsafe { *static_ptr.cast() }
101 }
102
103 dlsym_fn!(
105 unsafe fn CFRelease(cf: CFTypeRef);
107 );
108 dlsym_fn!(
109 unsafe fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID;
111 );
112
113 dlsym_fn!(
115 unsafe fn CFDataCreateWithBytesNoCopy(
117 allocator: CFAllocatorRef,
118 bytes: *const u8,
119 length: CFIndex,
120 bytes_deallocator: CFAllocatorRef,
121 ) -> CFDataRef;
122 );
123
124 dlsym_fn!(
126 unsafe fn CFPropertyListCreateWithData(
128 allocator: CFAllocatorRef,
129 data: CFDataRef,
130 options: CFOptionFlags,
131 format: *mut CFPropertyListFormat,
132 error: *mut CFErrorRef,
133 ) -> CFPropertyListRef;
134 );
135
136 dlsym_fn!(
138 unsafe fn CFStringGetTypeID() -> CFTypeID;
140 );
141 dlsym_fn!(
142 unsafe fn CFStringCreateWithCStringNoCopy(
144 alloc: CFAllocatorRef,
145 c_str: *const c_char,
146 encoding: CFStringEncoding,
147 contents_deallocator: CFAllocatorRef,
148 ) -> CFStringRef;
149 );
150 dlsym_fn!(
151 unsafe fn CFStringGetCString(
153 the_string: CFStringRef,
154 buffer: *mut c_char,
155 buffer_size: CFIndex,
156 encoding: CFStringEncoding,
157 ) -> Boolean;
158 );
159
160 dlsym_fn!(
162 unsafe fn CFDictionaryGetTypeID() -> CFTypeID;
164 );
165 dlsym_fn!(
166 unsafe fn CFDictionaryGetValue(
168 the_dict: CFDictionaryRef,
169 key: *const c_void,
170 ) -> *const c_void;
171 );
172}
173
174impl Drop for CFHandle {
175 fn drop(&mut self) {
176 let _ = unsafe { libc::dlclose(self.0) };
179 }
180}