1use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut};
2
3use crate::{arc, cf, define_cf_type};
4
5#[cfg(feature = "ns")]
6use crate::ns;
7
8define_cf_type!(
9 #[doc(alias = "CFDataRef")]
10 Data(cf::Type)
11);
12
13define_cf_type!(
14 #[doc(alias = "CFMutableDataRef")]
15 DataMut(Data)
16);
17
18impl Data {
19 #[doc(alias = "CFDataGetTypeID")]
20 #[inline]
21 pub fn type_id() -> cf::TypeId {
22 unsafe { CFDataGetTypeID() }
23 }
24
25 #[inline]
26 pub fn new_in(
27 bytes: *const u8,
28 length: cf::Index,
29 allocator: Option<&cf::Allocator>,
30 ) -> Option<arc::R<cf::Data>> {
31 unsafe { CFDataCreate(allocator, bytes, length) }
32 }
33
34 #[inline]
35 pub fn new(bytes: *const u8, length: cf::Index) -> Option<arc::R<cf::Data>> {
36 Self::new_in(bytes, length, None)
37 }
38
39 #[inline]
40 pub fn from_slice(slice: &[u8]) -> Option<arc::R<Self>> {
41 Self::new(slice.as_ptr(), slice.len() as _)
42 }
43
44 #[doc(alias = "length")]
45 #[inline]
46 pub fn len(&self) -> usize {
47 unsafe { CFDataGetLength(self) as _ }
48 }
49
50 #[inline]
51 pub fn is_empty(&self) -> bool {
52 self.len() == 0
53 }
54
55 #[inline]
56 pub fn copy_mut_in(
57 &self,
58 capacity: cf::Index,
59 allocator: Option<&cf::Allocator>,
60 ) -> Option<arc::R<DataMut>> {
61 unsafe { CFDataCreateMutableCopy(allocator, capacity, self) }
62 }
63
64 #[inline]
65 pub fn copy_mut(&self, capacity: usize) -> arc::R<DataMut> {
66 unsafe { self.copy_mut_in(capacity as _, None).unwrap_unchecked() }
67 }
68
69 #[inline]
70 pub fn bytes_ptr(&self) -> *const u8 {
71 unsafe { CFDataGetBytePtr(self) }
72 }
73
74 #[inline]
75 pub fn copy_bytes(&self, buffer: &mut [u8]) {
76 unsafe { self.get_bytes(cf::Range::new(0, buffer.len() as _), buffer.as_mut_ptr()) }
77 }
78
79 #[inline]
80 pub unsafe fn get_bytes(&self, range: cf::Range, buffer: *mut u8) {
81 unsafe { CFDataGetBytes(self, range, buffer) }
82 }
83
84 #[inline]
85 pub fn as_slice(&self) -> &[u8] {
86 unsafe { &*slice_from_raw_parts(self.bytes_ptr() as _, self.len()) }
87 }
88
89 #[cfg(feature = "ns")]
90 #[inline]
91 pub fn as_ns(&self) -> &ns::Data {
92 unsafe { std::mem::transmute(self) }
93 }
94}
95
96impl DataMut {
97 #[inline]
98 pub fn new_in(
99 capacity: cf::Index,
100 allocator: Option<&cf::Allocator>,
101 ) -> Option<arc::R<cf::DataMut>> {
102 unsafe { CFDataCreateMutable(allocator, capacity) }
103 }
104
105 #[inline]
106 pub fn with_capacity(capacity: usize) -> arc::R<DataMut> {
107 unsafe { Self::new_in(capacity as _, None).unwrap_unchecked() }
108 }
109
110 #[doc(alias = "CFDataAppendBytes")]
114 #[inline]
115 pub unsafe fn append_bytes(&mut self, bytes: *const u8, length: cf::Index) {
116 unsafe { CFDataAppendBytes(self, bytes, length) }
117 }
118
119 #[inline]
120 #[doc(alias = "CFDataAppendBytes")]
121 pub fn push_bytes(&mut self, bytes: &[u8]) {
122 unsafe { self.append_bytes(bytes.as_ptr(), bytes.len() as _) }
123 }
124
125 #[doc(alias = "CFDataGetMutableBytePtr")]
128 #[inline]
129 pub unsafe fn bytes_ptr_mut(&mut self) -> *mut u8 {
130 unsafe { CFDataGetMutableBytePtr(self) }
131 }
132
133 #[doc(alias = "CFDataSetLength")]
134 #[inline]
135 pub fn set_len(&mut self, len: cf::Index) {
136 unsafe { CFDataSetLength(self, len) }
137 }
138
139 #[inline]
140 pub fn as_mut_slice(&mut self) -> &mut [u8] {
141 unsafe { &mut *slice_from_raw_parts_mut(self.bytes_ptr_mut(), self.len()) }
142 }
143
144 #[cfg(feature = "ns")]
145 #[inline]
146 pub fn as_ns_mut(&mut self) -> &mut ns::DataMut {
147 unsafe { std::mem::transmute(self) }
148 }
149}
150
151impl From<&[u8]> for arc::R<Data> {
158 fn from(bytes: &[u8]) -> Self {
159 unsafe { Data::new(bytes.as_ptr(), bytes.len() as _).unwrap_unchecked() }
160 }
161}
162
163#[link(name = "CoreFoundation", kind = "framework")]
164unsafe extern "C-unwind" {
165 fn CFDataGetTypeID() -> cf::TypeId;
166 fn CFDataCreate(
167 allocator: Option<&cf::Allocator>,
168 bytes: *const u8,
169 length: cf::Index,
170 ) -> Option<arc::R<cf::Data>>;
171 fn CFDataGetLength(data: &Data) -> cf::Index;
172 fn CFDataCreateMutable(
173 allocator: Option<&cf::Allocator>,
174 capacity: cf::Index,
175 ) -> Option<arc::R<cf::DataMut>>;
176 fn CFDataAppendBytes(data: &DataMut, bytes: *const u8, length: cf::Index);
177 fn CFDataCreateMutableCopy(
178 allocator: Option<&cf::Allocator>,
179 capacity: cf::Index,
180 data: &Data,
181 ) -> Option<arc::R<DataMut>>;
182
183 fn CFDataGetBytePtr(data: &cf::Data) -> *const u8;
184 fn CFDataGetBytes(data: &cf::Data, range: cf::Range, buffer: *mut u8);
185
186 fn CFDataGetMutableBytePtr(data: &mut cf::DataMut) -> *mut u8;
187 fn CFDataSetLength(data: &mut cf::DataMut, length: cf::Index);
188}