use std::fmt;
use libc::c_void;
use crate::{declare_CFType, kernel::UInt8};
use super::{
kCFAllocatorDefault, CFAllocatorRef, CFIndex, CFRange, CFType, CFTypeID, CFTypeObject,
CFTypeRef,
};
#[derive(Debug)]
#[repr(C)]
pub struct __CFData(c_void);
pub type CFDataRef = *const __CFData;
declare_CFType! {
CFData, CFDataRef
}
#[derive(Debug)]
#[repr(u64)]
pub enum CFDataSearchFlags {
KCFDataSearchBackwards = 1 << 0,
KCFDataSearchAnchored = 1 << 1,
}
impl CFData {
pub unsafe fn create(
allocator: CFAllocatorRef,
bytes: *const UInt8,
length: CFIndex,
) -> CFData {
unsafe { Self::create_with_ref(CFDataCreate(allocator, bytes, length)) }
}
pub unsafe fn create_copy(allocator: CFAllocatorRef, data: CFDataRef) -> CFData {
Self::create_with_ref(CFDataCreateCopy(allocator, data))
}
pub unsafe fn create_with_bytes_no_copy(
allocator: CFAllocatorRef,
bytes: *const UInt8,
length: CFIndex,
bytes_deallocator: CFAllocatorRef,
) -> CFData {
Self::create_with_ref(CFDataCreateWithBytesNoCopy(
allocator,
bytes,
length,
bytes_deallocator,
))
}
pub unsafe fn get_byte_ptr(data: CFDataRef) -> *const UInt8 {
CFDataGetBytePtr(data)
}
pub unsafe fn get_bytes(data: CFDataRef, range: CFRange, buffer: *mut u8) {
CFDataGetBytes(data, range, buffer)
}
pub unsafe fn get_length(data: CFDataRef) -> CFIndex {
CFDataGetLength(data)
}
pub unsafe fn find(
data: CFDataRef,
data_to_find: CFDataRef,
search_range: CFRange,
compare_options: CFDataSearchFlags,
) -> CFRange {
CFDataFind(data, data_to_find, search_range, compare_options)
}
pub fn get_type_id() -> CFTypeID {
unsafe { CFDataGetTypeID() }
}
}
impl fmt::Debug for CFData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe {
write!(
f,
"{:?}",
CFType::copy_description(self.get_internal_object() as CFTypeRef)
)
}
}
}
impl From<&[u8]> for CFData {
fn from(value: &[u8]) -> Self {
unsafe {
Self::create_with_ref(CFDataCreate(
kCFAllocatorDefault,
value.as_ptr(),
value.len() as CFIndex,
))
}
}
}
extern "C" {
pub fn CFDataCreate(
allocator: CFAllocatorRef,
bytes: *const UInt8,
length: CFIndex,
) -> CFDataRef;
pub fn CFDataCreateCopy(allocator: CFAllocatorRef, data: CFDataRef) -> CFDataRef;
pub fn CFDataCreateWithBytesNoCopy(
allocator: CFAllocatorRef,
bytes: *const UInt8,
length: CFIndex,
bytes_deallocator: CFAllocatorRef,
) -> CFDataRef;
pub fn CFDataGetBytePtr(data: CFDataRef) -> *const UInt8;
pub fn CFDataGetBytes(data: CFDataRef, range: CFRange, buffer: *mut UInt8);
pub fn CFDataGetLength(data: CFDataRef) -> CFIndex;
pub fn CFDataFind(
data: CFDataRef,
data_to_find: CFDataRef,
search_range: CFRange,
compare_options: CFDataSearchFlags,
) -> CFRange;
pub fn CFDataGetTypeID() -> CFTypeID;
}