1 use std::mem; 2 use std::ops::Range; 3 use std::os::raw::c_void; 4 use std::slice; 5 6 use objc_id::Id; 7 use block::{Block, ConcreteBlock}; 8 use {INSObject, INSCopying, INSMutableCopying, NSRange}; 9 10 pub trait INSData : INSObject { 11 fn len(&self) -> usize { 12 unsafe { 13 msg_send![self, length] 14 } 15 } 16 17 fn bytes(&self) -> &[u8] { 18 let ptr: *const c_void = unsafe { msg_send![self, bytes] }; 19 // The bytes pointer may be null for length zero 20 let (ptr, len) = if ptr.is_null() { 21 (0x1 as *const u8, 0) 22 } else { 23 (ptr as *const u8, self.len()) 24 }; 25 unsafe { 26 slice::from_raw_parts(ptr, len) 27 } 28 } 29 30 fn with_bytes(bytes: &[u8]) -> Id<Self> { 31 let cls = Self::class(); 32 unsafe { 33 let obj: *mut Self = msg_send![cls, alloc]; 34 let obj: *mut Self = msg_send![obj, initWithBytes:bytes.as_ptr() 35 length:bytes.len()]; 36 Id::from_retained_ptr(obj) 37 } 38 } 39 40 fn from_vec(bytes: Vec<u8>) -> Id<Self> { 41 let capacity = bytes.capacity(); 42 let dealloc = ConcreteBlock::new(move |bytes: *mut c_void, len: usize| unsafe { 43 // Recreate the Vec and let it drop 44 let _ = Vec::from_raw_parts(bytes as *mut u8, len, capacity); 45 }); 46 let dealloc = dealloc.copy(); 47 let dealloc: &Block<(*mut c_void, usize), ()> = &dealloc; 48 49 let mut bytes = bytes; 50 let cls = Self::class(); 51 unsafe { 52 let obj: *mut Self = msg_send![cls, alloc]; 53 let obj: *mut Self = msg_send![obj, initWithBytesNoCopy:bytes.as_mut_ptr() 54 length:bytes.len() 55 deallocator:dealloc]; 56 mem::forget(bytes); 57 Id::from_retained_ptr(obj) 58 } 59 } 60 } 61 62 object_struct!(NSData); 63 64 impl INSData for NSData { } 65 66 impl INSCopying for NSData { 67 type Output = NSData; 68 } 69 70 impl INSMutableCopying for NSData { 71 type Output = NSMutableData; 72 } 73 74 pub trait INSMutableData : INSData { 75 fn bytes_mut(&mut self) -> &mut [u8] { 76 let ptr: *mut c_void = unsafe { msg_send![self, mutableBytes] }; 77 // The bytes pointer may be null for length zero 78 let (ptr, len) = if ptr.is_null() { 79 (0x1 as *mut u8, 0) 80 } else { 81 (ptr as *mut u8, self.len()) 82 }; 83 unsafe { 84 slice::from_raw_parts_mut(ptr, len) 85 } 86 } 87 88 fn set_len(&mut self, len: usize) { 89 unsafe { 90 let _: () = msg_send![self, setLength:len]; 91 } 92 } 93 94 fn append(&mut self, bytes: &[u8]) { 95 unsafe { 96 let _: () = msg_send![self, appendBytes:bytes.as_ptr() 97 length:bytes.len()]; 98 } 99 } 100 101 fn replace_range(&mut self, range: Range<usize>, bytes: &[u8]) { 102 let range = NSRange::from_range(range); 103 unsafe { 104 let _: () = msg_send![self, replaceBytesInRange:range 105 withBytes:bytes.as_ptr() 106 length:bytes.len()]; 107 } 108 } 109 110 fn set_bytes(&mut self, bytes: &[u8]) { 111 let len = self.len(); 112 self.replace_range(0..len, bytes); 113 } 114 } 115 116 object_struct!(NSMutableData); 117 118 impl INSData for NSMutableData { } 119 120 impl INSMutableData for NSMutableData { } 121 122 impl INSCopying for NSMutableData { 123 type Output = NSData; 124 } 125 126 impl INSMutableCopying for NSMutableData { 127 type Output = NSMutableData; 128 } 129 130 #[cfg(test)] 131 mod tests { 132 use INSObject; 133 use super::{INSData, INSMutableData, NSData, NSMutableData}; 134 135 #[test] 136 fn test_bytes() { 137 let bytes = [3, 7, 16, 52, 112, 19]; 138 let data = NSData::with_bytes(&bytes); 139 assert!(data.len() == bytes.len()); 140 assert!(data.bytes() == bytes); 141 } 142 143 #[test] 144 fn test_no_bytes() { 145 let data = NSData::new(); 146 assert!(Some(data.bytes()).is_some()); 147 } 148 149 #[test] 150 fn test_bytes_mut() { 151 let mut data = NSMutableData::with_bytes(&[7, 16]); 152 data.bytes_mut()[0] = 3; 153 assert!(data.bytes() == [3, 16]); 154 } 155 156 #[test] 157 fn test_set_len() { 158 let mut data = NSMutableData::with_bytes(&[7, 16]); 159 data.set_len(4); 160 assert!(data.len() == 4); 161 assert!(data.bytes() == [7, 16, 0, 0]); 162 163 data.set_len(1); 164 assert!(data.len() == 1); 165 assert!(data.bytes() == [7]); 166 } 167 168 #[test] 169 fn test_append() { 170 let mut data = NSMutableData::with_bytes(&[7, 16]); 171 data.append(&[3, 52]); 172 assert!(data.len() == 4); 173 assert!(data.bytes() == [7, 16, 3, 52]); 174 } 175 176 #[test] 177 fn test_replace() { 178 let mut data = NSMutableData::with_bytes(&[7, 16]); 179 data.replace_range(0..0, &[3]); 180 assert!(data.bytes() == [3, 7, 16]); 181 182 data.replace_range(1..2, &[52, 13]); 183 assert!(data.bytes() == [3, 52, 13, 16]); 184 185 data.replace_range(2..4, &[6]); 186 assert!(data.bytes() == [3, 52, 6]); 187 188 data.set_bytes(&[8, 17]); 189 assert!(data.bytes() == [8, 17]); 190 } 191 192 #[test] 193 fn test_from_vec() { 194 let bytes = vec![3, 7, 16]; 195 let bytes_ptr = bytes.as_ptr(); 196 197 let data = NSData::from_vec(bytes); 198 assert!(data.bytes().as_ptr() == bytes_ptr); 199 } 200 } 201