1use block::IntoConcreteBlock;
2use libc::c_void;
3use objc::{msg_send, sel, sel_impl};
4
5use crate::{object,
6 objective_c_runtime::{
7 macros::{interface_impl},
8 traits::{FromId, PNSObject},
9 },
10 utils::to_bool,
11};
12
13use super::{NSError, NSRange, NSString, UInt, NSURL};
14
15#[derive(Debug, Clone, Copy)]
17#[repr(u64)]
18pub enum NSDataReadingOptions {
19 MappedIfSafe = 1 << 0,
20 Uncached = 1 << 1,
22 MappedAlways = 1 << 3,
24}
25
26#[derive(Debug, Clone, Copy)]
28#[repr(u64)]
29pub enum NSDataWritingOptions {
30 Atomic = 1,
32 WithoutOverwriting = 2,
34 FileProtectionNone = 0x10000000,
36 FileProtectionComplete = 0x20000000,
38 FileProtectionMask = 0xf0000000,
40 FileProtectionCompleteUnlessOpen = 0x30000000,
42 FileProtectionCompleteUntilFirstUserAuthentication = 0x40000000,
44}
45
46#[derive(Debug, Clone, Copy)]
48#[repr(u64)]
49pub enum NSDataSearchOptions {
50 SearchBackwards = 1,
52 SearchAnchored = 2,
54}
55
56#[derive(Debug, Clone, Copy)]
58#[repr(u64)]
59pub enum NSDataBase64DecodingOptions {
60 None = 0,
61 IgnoreUnknownCharacters = 1,
63}
64
65#[derive(Debug, Clone, Copy)]
67#[repr(u64)]
68pub enum NSDataBase64EncodingOptions {
69 None = 0,
70 SixtyFourCharacterLineLength = 1,
72 SeventySixCharacterLineLength = 1 << 1,
74 EndLineWithCarriageReturn = 1 << 4,
76 EndLineWithLineFeed = 1 << 5,
78}
79
80#[derive(Debug, Clone, Copy)]
82#[repr(i64)]
83pub enum NSDataCompressionAlgorithm {
84 LZFSE = 0,
86 LZ4,
88 LZMA,
90 Zlib,
92}
93
94object! {
95 unsafe pub struct NSData;
97}
98
99#[interface_impl(NSObject)]
100impl NSData {
101 #[method]
106 pub fn data() -> Self
107 where
108 Self: Sized + FromId,
109 {
110 unsafe { Self::from_id(msg_send![Self::m_class(), data]) }
111 }
112
113 #[method]
115 pub fn data_with_bytes_length(bytes: *const c_void, length: UInt) -> Self
116 where
117 Self: Sized + FromId,
118 {
119 unsafe { Self::from_id(msg_send![Self::m_class(), dataWithBytes: bytes length: length]) }
120 }
121
122 #[method]
124 pub fn data_with_bytes_no_copy_length(bytes: *mut c_void, length: UInt) -> Self
125 where
126 Self: Sized + FromId,
127 {
128 unsafe {
129 Self::from_id(msg_send![Self::m_class(), dataWithBytesNoCopy: bytes
130 length: length])
131 }
132 }
133
134 #[method]
136 pub fn data_with_bytes_no_copy_length_free_when_done(
137 bytes: *mut c_void,
138 length: UInt,
139 b: bool,
140 ) -> Self
141 where
142 Self: Sized + FromId,
143 {
144 unsafe {
145 Self::from_id(
146 msg_send![Self::m_class(), dataWithBytesNoCopy:bytes length:length freeWhenDone:b],
147 )
148 }
149 }
150
151 #[method]
153 pub fn data_with_data(data: NSData) -> Self
154 where
155 Self: Sized + FromId,
156 {
157 unsafe { Self::from_id(msg_send![Self::m_class(), dataWithData: data]) }
158 }
159
160 #[method]
162 pub fn init_with_bytes_length(&mut self, bytes: *const c_void, length: UInt) -> Self
163 where
164 Self: Sized + FromId,
165 {
166 unsafe { Self::from_id(msg_send![self.m_self(), initWithBytes: bytes length: length]) }
167 }
168
169 #[method]
171 pub fn init_with_bytes_no_copy_length(&mut self, bytes: *mut c_void, length: UInt) -> Self
172 where
173 Self: Sized + FromId,
174 {
175 unsafe {
176 Self::from_id(msg_send![self.m_self(), initWithBytesNoCopy: bytes length: length])
177 }
178 }
179
180 #[method]
182 pub fn init_with_bytes_no_copy_length_deallocator<F>(
183 &mut self,
184 bytes: *mut c_void,
185 length: UInt,
186 deallocator: F,
187 ) -> Self
188 where
189 Self: Sized + FromId,
190 F: IntoConcreteBlock<(*mut c_void, UInt), Ret = ()> + 'static,
191 {
192 let deallocator = deallocator.into_concrete_block();
193 let deallocator = deallocator.copy();
194
195 unsafe {
196 Self::from_id(
197 msg_send![self.m_self(), initWithBytesNoCopy: bytes length: length deallocator: deallocator],
198 )
199 }
200 }
201
202 #[method]
204 pub fn init_with_bytes_no_copy_length_free_when_done(
205 &mut self,
206 bytes: *mut c_void,
207 length: UInt,
208 b: bool,
209 ) -> Self
210 where
211 Self: Sized + FromId,
212 {
213 unsafe {
214 Self::from_id(
215 msg_send![self.m_self(), initWithBytesNoCopy: bytes length: length freeWhenDone:b],
216 )
217 }
218 }
219
220 #[method]
222 pub fn init_with_data(&mut self, data: &NSData) -> Self
223 where
224 Self: Sized + FromId,
225 {
226 unsafe { Self::from_id(msg_send![self.m_self(), initWithData: data.m_self()]) }
227 }
228
229 #[method]
234 pub fn data_with_contents_of_file(path: &NSString) -> Self
235 where
236 Self: Sized + FromId,
237 {
238 unsafe { Self::from_id(msg_send![Self::m_class(), dataWithContentsOfFile: path.m_self()]) }
239 }
240
241 #[method]
243 pub fn data_with_contents_of_file_options(
244 path: &NSString,
245 read_options_mask: NSDataReadingOptions,
246 ) -> Result<Self, NSError>
247 where
248 Self: Sized + FromId,
249 {
250 let mut error = NSError::m_alloc();
251
252 unsafe {
253 let ptr = Self::from_id(
254 msg_send![Self::m_class(), dataWithContentsOfFile: path.m_self() options: read_options_mask error: &mut error],
255 );
256
257 if error.m_self().is_null() {
258 Ok(ptr)
259 } else {
260 Err(error)
261 }
262 }
263 }
264
265 #[method]
267 pub fn data_with_contents_of_url(url: &NSURL) -> Self
268 where
269 Self: Sized + FromId,
270 {
271 unsafe { Self::from_id(msg_send![Self::m_class(), dataWithContentsOfURL: url.m_self()]) }
272 }
273
274 #[method]
276 pub fn data_with_contents_of_url_options(
277 url: &NSURL,
278 read_options_mask: NSDataReadingOptions,
279 ) -> Result<Self, NSError>
280 where
281 Self: Sized + FromId,
282 {
283 let mut error = NSError::m_alloc();
284 unsafe {
285 let ptr = Self::from_id(
286 msg_send![Self::m_class(), dataWithContentsOfURL: url.m_self() options: read_options_mask error: &mut error],
287 );
288
289 if error.m_self().is_null() {
290 Ok(ptr)
291 } else {
292 Err(error)
293 }
294 }
295 }
296
297 #[method]
299 pub fn init_with_contents_of_file(&mut self, path: &NSString) -> Self
300 where
301 Self: Sized + FromId,
302 {
303 unsafe { Self::from_id(msg_send![self.m_self(), initWithContentsOfFile: path.m_self()]) }
304 }
305
306 #[method]
308 pub fn init_with_contents_of_file_options(
309 &mut self,
310 path: &NSString,
311 read_options_mask: NSDataReadingOptions,
312 ) -> Result<Self, NSError>
313 where
314 Self: Sized + FromId,
315 {
316 let mut error = NSError::m_alloc();
317
318 unsafe {
319 let ptr = Self::from_id(
320 msg_send![self.m_self(), initWithContentsOfFile: path.m_self() options: read_options_mask error: &mut error],
321 );
322
323 if error.m_self().is_null() {
324 Ok(ptr)
325 } else {
326 Err(error)
327 }
328 }
329 }
330
331 #[method]
333 pub fn init_with_contents_of_url(&mut self, url: &NSURL) -> Self
334 where
335 Self: Sized + FromId,
336 {
337 unsafe { Self::from_id(msg_send![self.m_self(), initWithContentsOfURL: url.m_self()]) }
338 }
339
340 #[method]
342 pub fn init_with_contents_of_url_options(
343 &mut self,
344 url: &NSURL,
345 read_options_mask: NSDataReadingOptions,
346 ) -> Result<Self, NSError>
347 where
348 Self: Sized + FromId,
349 {
350 let mut error = NSError::m_alloc();
351
352 unsafe {
353 let ptr = Self::from_id(
354 msg_send![self.m_self(), initWithContentsOfURL: url.m_self() options: read_options_mask error: &mut error],
355 );
356
357 if error.m_self().is_null() {
358 Ok(ptr)
359 } else {
360 Err(error)
361 }
362 }
363 }
364
365 #[method]
370 pub fn write_to_file_atomically(&self, path: &NSString, use_auxiliary_file: bool) -> bool {
371 unsafe {
372 to_bool(
373 msg_send![self.m_self(), writeToFile: path.m_self() atomically: use_auxiliary_file],
374 )
375 }
376 }
377
378 #[method]
380 pub fn write_to_file_options(
381 &self,
382 path: &NSString,
383 write_options: NSDataWritingOptions,
384 ) -> Result<bool, NSError> {
385 unsafe {
386 let mut error = NSError::m_alloc();
387
388 let ptr = to_bool(
389 msg_send![self.m_self(), writeToFile: path.m_self() options: write_options error: &mut error],
390 );
391
392 if error.m_self().is_null() {
393 Ok(ptr)
394 } else {
395 Err(error)
396 }
397 }
398 }
399
400 #[method]
402 pub fn write_to_url_atomically(&self, url: &NSURL, atomically: bool) -> bool {
403 unsafe {
404 to_bool(msg_send![self.m_self(), writeToURL: url.m_self() atomically: atomically])
405 }
406 }
407
408 #[method]
410 pub fn write_to_url_options(
411 &self,
412 url: &NSURL,
413 write_options: NSDataWritingOptions,
414 ) -> Result<bool, NSError> {
415 unsafe {
416 let mut error = NSError::m_alloc();
417
418 let ptr = to_bool(
419 msg_send![self.m_self(), writeToURL: url.m_self() options: write_options error: &mut error],
420 );
421
422 if error.m_self().is_null() {
423 Ok(ptr)
424 } else {
425 Err(error)
426 }
427 }
428 }
429
430 #[method]
435 pub fn init_with_base64_encoded_data_options(
436 &mut self,
437 base64_data: &NSData,
438 options: NSDataBase64DecodingOptions,
439 ) -> Self
440 where
441 Self: Sized + FromId,
442 {
443 unsafe {
444 Self::from_id(
445 msg_send![self.m_self(), initWithBase64EncodedData: base64_data.m_self() options: options],
446 )
447 }
448 }
449
450 #[method]
452 pub fn init_with_base64_encoded_string_options(
453 &mut self,
454 base64_string: &NSString,
455 options: NSDataBase64DecodingOptions,
456 ) -> Self
457 where
458 Self: Sized + FromId,
459 {
460 unsafe {
461 Self::from_id(
462 msg_send![self.m_self(), initWithBase64EncodedString: base64_string.m_self() options: options],
463 )
464 }
465 }
466
467 #[method]
469 pub fn base64_encoded_data_with_options(&self, options: NSDataBase64EncodingOptions) -> NSData {
470 unsafe {
471 NSData::from_id(msg_send![
472 self.m_self(),
473 base64EncodedDataWithOptions: options
474 ])
475 }
476 }
477
478 #[method]
480 pub fn base64_encoded_string_with_options(
481 &self,
482 options: NSDataBase64EncodingOptions,
483 ) -> NSString {
484 unsafe {
485 NSString::from_id(msg_send![
486 self.m_self(),
487 base64EncodedStringWithOptions: options
488 ])
489 }
490 }
491
492 #[property]
498 pub fn bytes(&self) -> *const c_void {
499 unsafe { msg_send![self.m_self(), bytes] }
500 }
501
502 #[method]
504 pub fn enumerate_byte_ranges_using_block<F>(&self, block: F)
505 where
506 F: IntoConcreteBlock<(*const c_void, NSRange, *mut bool), Ret = ()> + 'static,
507 {
508 unsafe {
509 let block = block.into_concrete_block();
510 let block = block.copy();
511
512 msg_send![self.m_self(), enumerateByteRangesUsingBlock: block]
513 }
514 }
515
516 #[method]
518 pub fn get_bytes_length(&self, buffer: *mut c_void, length: UInt) {
519 unsafe { msg_send![self.m_self(), getBytes: buffer length: length] }
520 }
521
522 #[method]
524 pub fn get_bytes_range(&self, buffer: *mut c_void, range: NSRange) {
525 unsafe { msg_send![self.m_self(), getBytes: buffer range: range] }
526 }
527
528 #[method]
533 pub fn subdata_with_range(&self, range: NSRange) -> NSData {
534 unsafe { NSData::from_id(msg_send![self.m_self(), subdataWithRange: range]) }
535 }
536
537 #[method]
539 pub fn range_of_data_options_range(
540 &self,
541 data_to_find: &NSData,
542 mask: NSDataSearchOptions,
543 search_range: NSRange,
544 ) -> NSRange {
545 unsafe {
546 msg_send![self.m_self(), rangeOfData: data_to_find.m_self() options: mask range:search_range]
547 }
548 }
549
550 #[method]
552 pub fn is_equal_to_data(&self, other: &NSData) -> bool {
553 unsafe { to_bool(msg_send![self.m_self(), isEqualToData: other.m_self()]) }
554 }
555
556 #[method]
558 pub fn length(&self) -> UInt {
559 unsafe { msg_send![self.m_self(), length] }
560 }
561
562 #[method]
567 pub fn compressed_data_using_algorithm(
568 &self,
569 algorithm: NSDataCompressionAlgorithm,
570 ) -> Result<Self, NSError>
571 where
572 Self: Sized + FromId,
573 {
574 let mut error = NSError::m_alloc();
575
576 unsafe {
577 let ptr = Self::from_id(
578 msg_send![self.m_self(), compressedDataUsingAlgorithm: algorithm error: &mut error],
579 );
580
581 if error.m_self().is_null() {
582 Ok(ptr)
583 } else {
584 Err(error)
585 }
586 }
587 }
588
589 #[method]
591 pub fn decompressed_data_using_algorithm(
592 &self,
593 algorithm: NSDataCompressionAlgorithm,
594 ) -> Result<Self, NSError>
595 where
596 Self: Sized + FromId,
597 {
598 let mut error = NSError::m_alloc();
599
600 unsafe {
601 let ptr = Self::from_id(
602 msg_send![self.m_self(), decompressedDataUsingAlgorithm: algorithm error: &mut error],
603 );
604
605 if error.m_self().is_null() {
606 Ok(ptr)
607 } else {
608 Err(error)
609 }
610 }
611 }
612}