Skip to content

Commit

Permalink
Refactor generic creation methods
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Aug 1, 2022
1 parent 7730428 commit 747baac
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 24 deletions.
20 changes: 12 additions & 8 deletions objc2/src/foundation/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,18 @@ impl<T: Message + RefUnwindSafe, O: Ownership> RefUnwindSafe for NSArray<T, O> {
impl<T: Message + RefUnwindSafe> UnwindSafe for NSArray<T, Shared> {}
impl<T: Message + UnwindSafe> UnwindSafe for NSArray<T, Owned> {}

pub(crate) unsafe fn from_refs<T: Message + ?Sized>(cls: &Class, refs: &[&T]) -> *mut Object {
let obj: *mut Object = unsafe { msg_send![cls, alloc] };
#[track_caller]
pub(crate) unsafe fn with_objects<T: Message + ?Sized, R: Message, O: Ownership>(
cls: &Class,
objects: &[&T],
) -> Id<R, O> {
unsafe {
msg_send![
obj,
initWithObjects: refs.as_ptr(),
count: refs.len(),
msg_send_id![
msg_send_id![cls, alloc],
initWithObjects: objects.as_ptr(),
count: objects.len(),
]
.expect("unexpected NULL array")
}
}

Expand Down Expand Up @@ -137,7 +141,7 @@ impl<T: Message, O: Ownership> NSArray<T, O> {
// but we would like to know when we're the only owner of the array, to
// allow mutation of the array's items.
pub fn from_vec(vec: Vec<Id<T, O>>) -> Id<Self, O> {
unsafe { Id::new(from_refs(Self::class(), vec.as_slice_ref()).cast()).unwrap() }
unsafe { with_objects(Self::class(), vec.as_slice_ref()) }
}

pub fn objects_in_range(&self, range: Range<usize>) -> Vec<&T> {
Expand Down Expand Up @@ -166,7 +170,7 @@ impl<T: Message, O: Ownership> NSArray<T, O> {

impl<T: Message> NSArray<T, Shared> {
pub fn from_slice(slice: &[Id<T, Shared>]) -> Id<Self, Shared> {
unsafe { Id::new(from_refs(Self::class(), slice.as_slice_ref()).cast()).unwrap() }
unsafe { with_objects(Self::class(), slice.as_slice_ref()) }
}

#[doc(alias = "objectAtIndex:")]
Expand Down
20 changes: 10 additions & 10 deletions objc2/src/foundation/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl NSData {
}

pub fn with_bytes(bytes: &[u8]) -> Id<Self, Shared> {
unsafe { Id::new(data_with_bytes(Self::class(), bytes).cast()).unwrap() }
unsafe { Id::cast(with_slice(Self::class(), bytes)) }
}

#[cfg(feature = "block")]
Expand All @@ -72,7 +72,7 @@ impl NSData {
#[cfg(not(feature = "gnustep-1-7"))]
let cls = Self::class();

unsafe { Id::new(data_from_vec(cls, bytes).cast()).unwrap() }
unsafe { Id::cast(with_vec(cls, bytes)) }
}
}

Expand Down Expand Up @@ -137,20 +137,20 @@ impl<'a> IntoIterator for &'a NSData {
}
}

pub(crate) unsafe fn data_with_bytes(cls: &Class, bytes: &[u8]) -> *mut Object {
pub(crate) unsafe fn with_slice(cls: &Class, bytes: &[u8]) -> Id<Object, Shared> {
let bytes_ptr: *const c_void = bytes.as_ptr().cast();
unsafe {
let obj: *mut Object = msg_send![cls, alloc];
msg_send![
obj,
msg_send_id![
msg_send_id![cls, alloc],
initWithBytes: bytes_ptr,
length: bytes.len(),
]
.expect("unexpected NULL data")
}
}

#[cfg(feature = "block")]
pub(crate) unsafe fn data_from_vec(cls: &Class, bytes: Vec<u8>) -> *mut Object {
pub(crate) unsafe fn with_vec(cls: &Class, bytes: Vec<u8>) -> Id<Object, Shared> {
use core::mem::ManuallyDrop;

use block2::{Block, ConcreteBlock};
Expand All @@ -168,13 +168,13 @@ pub(crate) unsafe fn data_from_vec(cls: &Class, bytes: Vec<u8>) -> *mut Object {
let bytes_ptr: *mut c_void = bytes.as_mut_ptr().cast();

unsafe {
let obj: *mut Object = msg_send![cls, alloc];
msg_send![
obj,
msg_send_id![
msg_send_id![cls, alloc],
initWithBytesNoCopy: bytes_ptr,
length: bytes.len(),
deallocator: dealloc,
]
.expect("unexpected NULL data")
}
}

Expand Down
6 changes: 3 additions & 3 deletions objc2/src/foundation/mutable_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::fmt;
use core::marker::PhantomData;
use core::ops::{Index, IndexMut};

use super::array::from_refs;
use super::array::with_objects;
use super::{
NSArray, NSComparisonResult, NSCopying, NSFastEnumeration, NSFastEnumerator, NSMutableCopying,
NSObject,
Expand Down Expand Up @@ -41,13 +41,13 @@ impl<T: Message, O: Ownership> NSMutableArray<T, O> {
}

pub fn from_vec(vec: Vec<Id<T, O>>) -> Id<Self, Owned> {
unsafe { Id::new(from_refs(Self::class(), vec.as_slice_ref()).cast()).unwrap() }
unsafe { with_objects(Self::class(), vec.as_slice_ref()) }
}
}

impl<T: Message> NSMutableArray<T, Shared> {
pub fn from_slice(slice: &[Id<T, Shared>]) -> Id<Self, Owned> {
unsafe { Id::new(from_refs(Self::class(), slice.as_slice_ref()).cast()).unwrap() }
unsafe { with_objects(Self::class(), slice.as_slice_ref()) }
}
}

Expand Down
6 changes: 3 additions & 3 deletions objc2/src/foundation/mutable_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::ops::{Index, IndexMut, Range};
use core::slice::{self, SliceIndex};
use std::io;

use super::data::data_with_bytes;
use super::data::with_slice;
use super::{NSCopying, NSData, NSMutableCopying, NSObject, NSRange};
use crate::rc::{DefaultId, Id, Owned, Shared};
use crate::{extern_class, msg_send, msg_send_id};
Expand All @@ -30,12 +30,12 @@ impl NSMutableData {
}

pub fn with_bytes(bytes: &[u8]) -> Id<Self, Owned> {
unsafe { Id::new(data_with_bytes(Self::class(), bytes).cast()).unwrap() }
unsafe { Id::from_shared(Id::cast(with_slice(Self::class(), bytes))) }
}

#[cfg(feature = "block")]
pub fn from_vec(bytes: Vec<u8>) -> Id<Self, Owned> {
unsafe { Id::new(super::data::data_from_vec(Self::class(), bytes).cast()).unwrap() }
unsafe { Id::from_shared(Id::cast(super::data::with_vec(Self::class(), bytes))) }
}

// TODO: Use malloc_buf/mbox and `initWithBytesNoCopy:...`?
Expand Down

0 comments on commit 747baac

Please sign in to comment.