#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals, improper_ctypes)]
use core::ffi::c_void;
use core::ops::Deref;
use std::ffi::c_char;
#[cfg(target_pointer_width = "64")]
pub type CGFloat = core::ffi::c_double;
#[cfg(not(target_pointer_width = "64"))]
pub type CGFloat = core::ffi::c_float;
pub type UInt8 = core::ffi::c_uchar;
pub type UInt16 = core::ffi::c_ushort;
pub type SInt16 = core::ffi::c_short;
pub type SInt32 = core::ffi::c_int;
pub type UInt32 = core::ffi::c_uint;
pub type Boolean = u8;
pub type CFIndex = isize;
pub type CFHashCode = usize;
pub type CFRef = *const c_void;
pub type CFAllocatorRef = *const c_void;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct CFRange {
pub location: CFIndex,
pub length: CFIndex,
}
impl CFRange {
pub fn init(location: CFIndex, length: CFIndex) -> CFRange {
CFRange { location, length }
}
}
#[repr(C)]
pub struct __CFValue(c_void);
pub type CFValueRef = *const __CFValue;
pub struct CFValue(CFValueRef);
impl CFValue {
#[inline]
pub fn get_rule(reference: CFValueRef) -> Self {
assert!(!reference.is_null());
unsafe { Self::create_rule(CFRetain(reference as _) as _) }
}
#[inline]
pub fn create_rule(reference: CFValueRef) -> Self {
assert!(!reference.is_null());
CFValue(reference)
}
#[inline]
pub fn as_ref(&self) -> CFValueRef {
self.0
}
#[inline]
pub fn as_cf(&self) -> CFRef {
self.0 as CFRef
}
}
impl Drop for CFValue {
fn drop(&mut self) {
unsafe { CFRelease(self.as_ref() as _) }
}
}
impl Clone for CFValue {
fn clone(&self) -> Self {
Self::get_rule(self.0)
}
}
pub type CFNumberRef = CFValueRef;
#[derive(Clone)]
pub struct CFNumber(pub CFValue);
impl Deref for CFNumber {
type Target = CFValue;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<CFNumber> for CFValue {
fn from(value: CFNumber) -> Self {
value.0
}
}
impl From<i32> for CFNumber {
#[inline]
fn from(value: i32) -> Self {
unsafe {
let number_ref = CFNumberCreate(
kCFAllocatorDefault, kCFNumberSInt32Type,
&value as *const i32 as _,
);
CFNumber(CFValue::create_rule(number_ref))
}
}
}
impl From<i64> for CFNumber {
#[inline]
fn from(value: i64) -> Self {
unsafe {
let number_ref = CFNumberCreate(
kCFAllocatorDefault, kCFNumberSInt64Type,
&value as *const i64 as _,
);
CFNumber(CFValue::create_rule(number_ref))
}
}
}
impl From<f32> for CFNumber {
#[inline]
fn from(value: f32) -> Self {
unsafe {
let number_ref = CFNumberCreate(
kCFAllocatorDefault, kCFNumberFloat32Type,
&value as *const f32 as _,
);
CFNumber(CFValue::create_rule(number_ref))
}
}
}
impl From<f64> for CFNumber {
#[inline]
fn from(value: f64) -> Self {
unsafe {
let number_ref = CFNumberCreate(
kCFAllocatorDefault, kCFNumberFloat64Type,
&value as *const f64 as _,
);
CFNumber(CFValue::create_rule(number_ref))
}
}
}
pub type CFArrayRef = CFValueRef;
#[derive(Clone)]
pub struct CFArray(pub CFValue);
impl Deref for CFArray {
type Target = CFValue;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<CFArray> for CFValue {
fn from(value: CFArray) -> Self {
value.0
}
}
impl CFArray {
#[inline]
pub fn len(&self) -> CFIndex {
unsafe { CFArrayGetCount(self.as_ref()) }
}
#[inline]
pub fn get(&self, index: CFIndex) -> Option<CFRef> {
if index < self.len() {
let v = unsafe { CFArrayGetValueAtIndex(self.as_ref(), index) };
if !v.is_null() {
Some(v)
} else {
None
}
} else {
None
}
}
}
pub type CFStringRef = CFValueRef;
#[derive(Clone)]
pub struct CFString(pub CFValue);
impl Deref for CFString {
type Target = CFValue;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<CFString> for CFValue {
fn from(value: CFString) -> Self {
value.0
}
}
impl CFString {
#[inline]
pub fn new(string: &str) -> CFString {
unsafe {
let string_ref = CFStringCreateWithBytes(
kCFAllocatorDefault,
string.as_ptr(),
string.len() as _,
kCFStringEncodingUTF8,
false as Boolean,
);
CFString(CFValue::create_rule(string_ref))
}
}
#[inline]
pub fn from_static_string(string: &'static str) -> CFString {
unsafe {
let string_ref = CFStringCreateWithBytesNoCopy(
kCFAllocatorDefault,
string.as_ptr(),
string.len() as _,
kCFStringEncodingUTF8,
false as Boolean,
kCFAllocatorNull,
);
CFString(CFValue::create_rule(string_ref))
}
}
#[inline]
pub fn char_len(&self) -> CFIndex {
unsafe { CFStringGetLength(self.as_ref()) }
}
}
mod string {
use super::*;
use core::{fmt, str};
use std::borrow::Cow;
use std::ffi::CStr;
use std::ptr;
impl<'a> From<&'a CFString> for Cow<'a, str> {
fn from(cf_str: &'a CFString) -> Cow<'a, str> {
unsafe {
let c_string = CFStringGetCStringPtr(cf_str.as_ref(), kCFStringEncodingUTF8);
if !c_string.is_null() {
let c_str = CStr::from_ptr(c_string);
Cow::Borrowed(str::from_utf8_unchecked(c_str.to_bytes()))
} else {
let char_len = cf_str.char_len();
let mut bytes_required: CFIndex = 0;
CFStringGetBytes(
cf_str.as_ref(),
CFRange {
location: 0,
length: char_len,
},
kCFStringEncodingUTF8,
0,
false as Boolean,
ptr::null_mut(),
0,
&mut bytes_required,
);
let mut buffer = vec![b'\x00'; bytes_required as usize];
let mut bytes_used: CFIndex = 0;
let chars_written = CFStringGetBytes(
cf_str.as_ref(),
CFRange {
location: 0,
length: char_len,
},
kCFStringEncodingUTF8,
0,
false as Boolean,
buffer.as_mut_ptr(),
buffer.len() as _,
&mut bytes_used,
);
assert_eq!(chars_written, char_len);
assert_eq!(bytes_used, buffer.len() as _);
Cow::Owned(String::from_utf8_unchecked(buffer))
}
}
}
}
impl fmt::Display for CFString {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(&Cow::from(self))
}
}
impl fmt::Debug for CFString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\"{}\"", self)
}
}
}
type CFURLRef = CFValueRef;
#[derive(Clone)]
pub struct CFURL(pub CFValue);
impl Deref for CFURL {
type Target = CFValue;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<CFURL> for CFValue {
fn from(value: CFURL) -> Self {
value.0
}
}
#[cfg(target_vendor = "apple")]
mod cfurl {
use super::*;
impl CFURL {
pub fn to_path(&self) -> Option<std::path::PathBuf> {
unsafe {
let mut buf = [0u8; 1024 as usize];
let result = CFURLGetFileSystemRepresentation(self.as_ref(), true as Boolean, buf.as_mut_ptr(), buf.len() as CFIndex);
if result == false as Boolean {
return None;
}
use std::ffi::CStr;
let len = CStr::from_ptr(buf.as_ptr() as _).count_bytes();
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt as _;
let path = OsStr::from_bytes(&buf[0..len]);
Some(path.into())
}
}
}
}
#[cfg(not(target_vendor = "apple"))]
mod cfurl {
use super::*;
impl CFURL {
pub fn to_path(&self) -> Option<std::path::PathBuf> {
None
}
}
}
pub type CFDictionaryRef = CFValueRef;
#[derive(Clone)]
pub struct CFDictionary(pub CFValue);
impl Deref for CFDictionary {
type Target = CFValue;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<CFDictionary> for CFValue {
fn from(value: CFDictionary) -> Self {
value.0
}
}
impl CFDictionary {
pub fn from_pairs(pairs: &[(CFValueRef, CFValue)]) -> CFDictionary {
let (keys, values): (Vec<CFRef>, Vec<CFRef>) = pairs.iter().map(|(key, value)| (*key as CFRef, value.as_cf())).unzip();
unsafe {
let dictionary_ref = CFDictionaryCreate(
kCFAllocatorDefault,
keys.as_ptr(),
values.as_ptr(),
keys.len() as _,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks,
);
Self(CFValue::create_rule(dictionary_ref))
}
}
}
pub type CFNumberType = u32;
pub const kCFNumberSInt8Type: CFNumberType = 1;
pub const kCFNumberSInt16Type: CFNumberType = 2;
pub const kCFNumberSInt32Type: CFNumberType = 3;
pub const kCFNumberSInt64Type: CFNumberType = 4;
pub const kCFNumberFloat32Type: CFNumberType = 5;
pub const kCFNumberFloat64Type: CFNumberType = 6;
pub const kCFNumberCharType: CFNumberType = 7;
pub const kCFNumberShortType: CFNumberType = 8;
pub const kCFNumberIntType: CFNumberType = 9;
pub const kCFNumberLongType: CFNumberType = 10;
pub const kCFNumberLongLongType: CFNumberType = 11;
pub const kCFNumberFloatType: CFNumberType = 12;
pub const kCFNumberDoubleType: CFNumberType = 13;
pub const kCFNumberCFIndexType: CFNumberType = 14;
pub const kCFNumberNSIntegerType: CFNumberType = 15;
pub const kCFNumberCGFloatType: CFNumberType = 16;
pub const kCFNumberMaxType: CFNumberType = 16;
pub type CFStringEncoding = UInt32;
pub const kCFStringEncodingUTF8: CFStringEncoding = 0x08000100;
pub type CFDictionaryApplierFunction = extern "C" fn(key: *const c_void, value: *const c_void, context: *mut c_void);
pub type CFDictionaryRetainCallBack = extern "C" fn(allocator: CFAllocatorRef, value: *const c_void) -> *const c_void;
pub type CFDictionaryReleaseCallBack = extern "C" fn(allocator: CFAllocatorRef, value: *const c_void);
pub type CFDictionaryCopyDescriptionCallBack = extern "C" fn(value: *const c_void) -> CFStringRef;
pub type CFDictionaryEqualCallBack = extern "C" fn(value1: *const c_void, value2: *const c_void) -> Boolean;
pub type CFDictionaryHashCallBack = extern "C" fn(value: *const c_void) -> CFHashCode;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CFDictionaryKeyCallBacks {
pub version: CFIndex,
pub retain: CFDictionaryRetainCallBack,
pub release: CFDictionaryReleaseCallBack,
pub copyDescription: CFDictionaryCopyDescriptionCallBack,
pub equal: CFDictionaryEqualCallBack,
pub hash: CFDictionaryHashCallBack,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CFDictionaryValueCallBacks {
pub version: CFIndex,
pub retain: CFDictionaryRetainCallBack,
pub release: CFDictionaryReleaseCallBack,
pub copyDescription: CFDictionaryCopyDescriptionCallBack,
pub equal: CFDictionaryEqualCallBack,
}
#[link(name = "CoreFoundation", kind = "framework")]
extern "C" {
pub fn CFRelease(cf: CFRef);
pub fn CFRetain(cf: CFRef) -> CFRef;
pub static kCFAllocatorDefault: CFAllocatorRef;
pub static kCFAllocatorSystemDefault: CFAllocatorRef;
pub static kCFAllocatorMalloc: CFAllocatorRef;
pub static kCFAllocatorMallocZone: CFAllocatorRef;
pub static kCFAllocatorNull: CFAllocatorRef;
pub static kCFAllocatorUseContext: CFAllocatorRef;
pub fn CFNumberCreate(allocator: CFAllocatorRef, theType: CFNumberType, valuePtr: *const c_void) -> CFNumberRef;
pub fn CFStringCreateWithBytes(
alloc: CFAllocatorRef,
bytes: *const UInt8,
numBytes: CFIndex,
encoding: CFStringEncoding,
isExternalRepresentation: Boolean,
) -> CFStringRef;
pub fn CFStringCreateWithBytesNoCopy(
alloc: CFAllocatorRef,
bytes: *const UInt8,
numBytes: CFIndex,
encoding: CFStringEncoding,
isExternalRepresentation: Boolean,
contentsDeallocator: CFAllocatorRef,
) -> CFStringRef;
pub fn CFStringGetBytes(
theString: CFStringRef,
range: CFRange,
encoding: CFStringEncoding,
lossByte: UInt8,
isExternalRepresentation: Boolean,
buffer: *mut UInt8,
maxBufLen: CFIndex,
usedBufLen: *mut CFIndex,
) -> CFIndex;
pub fn CFStringGetCStringPtr(theString: CFStringRef, encoding: CFStringEncoding) -> *const c_char;
pub fn CFStringGetLength(theString: CFStringRef) -> CFIndex;
pub fn CFURLGetFileSystemRepresentation(anURL: CFURLRef, resolveAgainstBase: Boolean, buffer: *mut u8, maxBufLen: CFIndex) -> Boolean;
pub fn CFURLGetString(anURL: CFURLRef) -> CFStringRef;
pub static kCFTypeDictionaryKeyCallBacks: CFDictionaryKeyCallBacks;
pub static kCFCopyStringDictionaryKeyCallBacks: CFDictionaryKeyCallBacks;
pub static kCFTypeDictionaryValueCallBacks: CFDictionaryValueCallBacks;
pub fn CFDictionaryCreate(
allocator: CFAllocatorRef,
keys: *const *const c_void,
values: *const *const c_void,
numValues: CFIndex,
keyCallBacks: *const CFDictionaryKeyCallBacks,
valueCallBacks: *const CFDictionaryValueCallBacks,
) -> CFDictionaryRef;
pub fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex;
pub fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *const c_void;
}