rust_macios/core_foundation/
cf_data.rs

1use std::fmt;
2
3use libc::c_void;
4
5use crate::{declare_CFType, kernel::UInt8};
6
7use super::{
8    kCFAllocatorDefault, CFAllocatorRef, CFIndex, CFRange, CFType, CFTypeID, CFTypeObject,
9    CFTypeRef,
10};
11
12#[derive(Debug)]
13#[repr(C)]
14pub struct __CFData(c_void);
15
16/// This provides support for data objects, object-oriented wrappers for byte buffer
17pub type CFDataRef = *const __CFData;
18
19declare_CFType! {
20    /// This provides support for data objects, object-oriented wrappers for byte buffer
21    CFData, CFDataRef
22}
23
24/// A CFOptionFlags type for specifying options for searching.
25#[derive(Debug)]
26#[repr(u64)]
27pub enum CFDataSearchFlags {
28    ///
29    KCFDataSearchBackwards = 1 << 0,
30    ///
31    KCFDataSearchAnchored = 1 << 1,
32}
33
34impl CFData {
35    /// Creates an immutable CFData object using data copied from a specified byte buffer.
36    ///
37    /// # Safety
38    ///
39    /// This function dereferences a raw pointer
40    pub unsafe fn create(
41        allocator: CFAllocatorRef,
42        bytes: *const UInt8,
43        length: CFIndex,
44    ) -> CFData {
45        unsafe { Self::create_with_ref(CFDataCreate(allocator, bytes, length)) }
46    }
47
48    /// Creates an immutable copy of a CFData object.
49    //
50    /// # Safety
51    ///
52    /// This function dereferences a raw pointer
53    pub unsafe fn create_copy(allocator: CFAllocatorRef, data: CFDataRef) -> CFData {
54        Self::create_with_ref(CFDataCreateCopy(allocator, data))
55    }
56
57    /// Creates an immutable CFData object from an external (client-owned) byte buffer.
58    ///
59    /// # Safety
60    ///
61    /// This function dereferences a raw pointer
62    pub unsafe fn create_with_bytes_no_copy(
63        allocator: CFAllocatorRef,
64        bytes: *const UInt8,
65        length: CFIndex,
66        bytes_deallocator: CFAllocatorRef,
67    ) -> CFData {
68        Self::create_with_ref(CFDataCreateWithBytesNoCopy(
69            allocator,
70            bytes,
71            length,
72            bytes_deallocator,
73        ))
74    }
75
76    /// Returns a read-only pointer to the bytes of a CFData object.
77    ///
78    /// # Safety
79    ///
80    /// This function dereferences a raw pointer
81    pub unsafe fn get_byte_ptr(data: CFDataRef) -> *const UInt8 {
82        CFDataGetBytePtr(data)
83    }
84
85    /// Copies the byte contents of a CFData object to an external buffer.
86    ///
87    /// # Safety
88    ///
89    /// This function dereferences a raw pointer
90    pub unsafe fn get_bytes(data: CFDataRef, range: CFRange, buffer: *mut u8) {
91        CFDataGetBytes(data, range, buffer)
92    }
93
94    /// Returns the number of bytes contained by a CFData object.
95    ///
96    /// # Safety
97    ///
98    /// This function dereferences a raw pointer
99    pub unsafe fn get_length(data: CFDataRef) -> CFIndex {
100        CFDataGetLength(data)
101    }
102
103    /// Finds and returns the range within a data object of the first occurrence of the given data, within a given range, subject to any given options.
104    ///
105    /// # Safety
106    ///
107    /// This function dereferences a raw pointer
108    pub unsafe fn find(
109        data: CFDataRef,
110        data_to_find: CFDataRef,
111        search_range: CFRange,
112        compare_options: CFDataSearchFlags,
113    ) -> CFRange {
114        CFDataFind(data, data_to_find, search_range, compare_options)
115    }
116
117    /// Returns the type identifier for the CFData opaque type.
118    pub fn get_type_id() -> CFTypeID {
119        unsafe { CFDataGetTypeID() }
120    }
121}
122
123impl fmt::Debug for CFData {
124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125        unsafe {
126            write!(
127                f,
128                "{:?}",
129                CFType::copy_description(self.get_internal_object() as CFTypeRef)
130            )
131        }
132    }
133}
134
135impl From<&[u8]> for CFData {
136    fn from(value: &[u8]) -> Self {
137        unsafe {
138            Self::create_with_ref(CFDataCreate(
139                kCFAllocatorDefault,
140                value.as_ptr(),
141                value.len() as CFIndex,
142            ))
143        }
144    }
145}
146
147extern "C" {
148    /* Creating a CFData Object
149     */
150
151    pub fn CFDataCreate(
152        allocator: CFAllocatorRef,
153        bytes: *const UInt8,
154        length: CFIndex,
155    ) -> CFDataRef;
156
157    pub fn CFDataCreateCopy(allocator: CFAllocatorRef, data: CFDataRef) -> CFDataRef;
158    pub fn CFDataCreateWithBytesNoCopy(
159        allocator: CFAllocatorRef,
160        bytes: *const UInt8,
161        length: CFIndex,
162        bytes_deallocator: CFAllocatorRef,
163    ) -> CFDataRef;
164
165    /* Examining a CFData Object
166     */
167
168    pub fn CFDataGetBytePtr(data: CFDataRef) -> *const UInt8;
169
170    pub fn CFDataGetBytes(data: CFDataRef, range: CFRange, buffer: *mut UInt8);
171
172    pub fn CFDataGetLength(data: CFDataRef) -> CFIndex;
173
174    pub fn CFDataFind(
175        data: CFDataRef,
176        data_to_find: CFDataRef,
177        search_range: CFRange,
178        compare_options: CFDataSearchFlags,
179    ) -> CFRange;
180
181    /* Getting the CFData Type ID
182     */
183
184    pub fn CFDataGetTypeID() -> CFTypeID;
185}