Skip to content

Commit

Permalink
Improve NSMutableData
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Oct 31, 2021
1 parent 063d612 commit 0b42ca9
Showing 1 changed file with 48 additions and 34 deletions.
82 changes: 48 additions & 34 deletions objc2_foundation/src/data.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[cfg(feature = "block")]
use alloc::vec::Vec;
use core::ops::Range;
use core::ops::{Deref, DerefMut, Range};
use core::slice;
use core::{ffi::c_void, ptr::NonNull};

Expand Down Expand Up @@ -98,45 +98,45 @@ unsafe impl INSMutableCopying for NSData {
type Output = NSMutableData;
}

impl Deref for NSData {
type Target = [u8];

fn deref(&self) -> &[u8] {
self.bytes()
}
}

pub unsafe trait INSMutableData: INSData {
fn bytes_mut(&mut self) -> &mut [u8] {
let ptr: *mut c_void = unsafe { msg_send![self, mutableBytes] };
// The bytes pointer may be null for length zero
let (ptr, len) = if ptr.is_null() {
(0x1 as *mut u8, 0)
if ptr.is_null() {
&mut []
} else {
(ptr as *mut u8, self.len())
};
unsafe { slice::from_raw_parts_mut(ptr, len) }
unsafe { slice::from_raw_parts_mut(ptr as *mut u8, self.len()) }
}
}

/// Expands with zeroes, or truncates the buffer.
fn set_len(&mut self, len: usize) {
unsafe {
let _: () = msg_send![self, setLength: len];
}
unsafe { msg_send![self, setLength: len] }
}

fn append(&mut self, bytes: &[u8]) {
let bytes_ptr = bytes.as_ptr() as *const c_void;
unsafe {
let _: () = msg_send![
self,
appendBytes: bytes_ptr,
length:bytes.len(),
];
}
unsafe { msg_send![self, appendBytes: bytes_ptr, length: bytes.len()] }
}

fn replace_range(&mut self, range: Range<usize>, bytes: &[u8]) {
let range = NSRange::from(range);
let bytes_ptr = bytes.as_ptr() as *const c_void;
unsafe {
let _: () = msg_send![
msg_send![
self,
replaceBytesInRange:range,
withBytes:bytes_ptr,
length:bytes.len(),
];
replaceBytesInRange: range,
withBytes: bytes_ptr,
length: bytes.len(),
]
}
}

Expand All @@ -160,6 +160,20 @@ unsafe impl INSMutableCopying for NSMutableData {
type Output = NSMutableData;
}

impl Deref for NSMutableData {
type Target = [u8];

fn deref(&self) -> &[u8] {
self.bytes()
}
}

impl DerefMut for NSMutableData {
fn deref_mut(&mut self) -> &mut [u8] {
self.bytes_mut()
}
}

#[cfg(test)]
mod tests {
use super::{INSData, INSMutableData, NSData, NSMutableData};
Expand All @@ -171,8 +185,8 @@ mod tests {
fn test_bytes() {
let bytes = [3, 7, 16, 52, 112, 19];
let data = NSData::with_bytes(&bytes);
assert!(data.len() == bytes.len());
assert!(data.bytes() == bytes);
assert_eq!(data.len(), bytes.len());
assert_eq!(data.bytes(), bytes);
}

#[test]
Expand All @@ -185,43 +199,43 @@ mod tests {
fn test_bytes_mut() {
let mut data = NSMutableData::with_bytes(&[7, 16]);
data.bytes_mut()[0] = 3;
assert!(data.bytes() == [3, 16]);
assert_eq!(data.bytes(), [3, 16]);
}

#[test]
fn test_set_len() {
let mut data = NSMutableData::with_bytes(&[7, 16]);
data.set_len(4);
assert!(data.len() == 4);
assert!(data.bytes() == [7, 16, 0, 0]);
assert_eq!(data.len(), 4);
assert_eq!(data.bytes(), [7, 16, 0, 0]);

data.set_len(1);
assert!(data.len() == 1);
assert!(data.bytes() == [7]);
assert_eq!(data.len(), 1);
assert_eq!(data.bytes(), [7]);
}

#[test]
fn test_append() {
let mut data = NSMutableData::with_bytes(&[7, 16]);
data.append(&[3, 52]);
assert!(data.len() == 4);
assert!(data.bytes() == [7, 16, 3, 52]);
assert_eq!(data.len(), 4);
assert_eq!(data.bytes(), [7, 16, 3, 52]);
}

#[test]
fn test_replace() {
let mut data = NSMutableData::with_bytes(&[7, 16]);
data.replace_range(0..0, &[3]);
assert!(data.bytes() == [3, 7, 16]);
assert_eq!(data.bytes(), [3, 7, 16]);

data.replace_range(1..2, &[52, 13]);
assert!(data.bytes() == [3, 52, 13, 16]);
assert_eq!(data.bytes(), [3, 52, 13, 16]);

data.replace_range(2..4, &[6]);
assert!(data.bytes() == [3, 52, 6]);
assert_eq!(data.bytes(), [3, 52, 6]);

data.set_bytes(&[8, 17]);
assert!(data.bytes() == [8, 17]);
assert_eq!(data.bytes(), [8, 17]);
}

#[cfg(feature = "block")]
Expand Down

0 comments on commit 0b42ca9

Please sign in to comment.