-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Raw pointer API for publisher and subscriber
- Loading branch information
1 parent
f04a339
commit 42de1c0
Showing
10 changed files
with
397 additions
and
166 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-FileCopyrightText: © Contributors to the iceoryx-rs project | ||
// SPDX-FileContributor: Mathias Kraus | ||
|
||
use crate::ChunkHeader; | ||
|
||
use std::ffi::c_void; | ||
use std::fmt; | ||
use std::slice; | ||
|
||
#[repr(transparent)] | ||
pub struct RawSample<T: ?Sized> { | ||
payload: *const T, | ||
} | ||
|
||
impl<T: ?Sized> RawSample<T> { | ||
#[inline] | ||
pub unsafe fn new_unchecked(payload: *const T) -> Self { | ||
debug_assert!( | ||
!payload.is_null(), | ||
"RawSample::new_unchecked requires that the payload pointer is non-null" | ||
); | ||
Self { payload } | ||
} | ||
|
||
#[allow(clippy::not_unsafe_ptr_arg_deref)] // false positive | ||
#[inline] | ||
pub fn new(payload: *const T) -> Option<Self> { | ||
if !payload.is_null() { | ||
// SAFETY: `payload` pointer is checked to be non-null | ||
Some(unsafe { Self::new_unchecked(payload) }) | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
#[must_use] | ||
#[inline] | ||
pub fn cast<U>(self) -> RawSample<U> { | ||
// SAFETY: `self.as_payload_ptr` returns a non-null ptr | ||
unsafe { RawSample::new_unchecked(self.as_payload_ptr().cast::<U>()) } | ||
} | ||
|
||
#[must_use] | ||
#[inline(always)] | ||
pub fn as_payload_ptr(self) -> *const T { | ||
self.payload | ||
} | ||
|
||
#[must_use] | ||
#[inline] | ||
pub fn chunk_header(&self) -> &ChunkHeader { | ||
unsafe { | ||
ChunkHeader::from_user_payload_unchecked(self.as_payload_ptr() as *const c_void) | ||
.expect("Valid chunk header from payload!") | ||
} | ||
} | ||
} | ||
|
||
impl<T> RawSample<[T]> { | ||
#[must_use] | ||
#[inline] | ||
pub fn slice_from_raw_parts(sample: RawSample<T>, len: usize) -> RawSample<[T]> { | ||
// SAFETY: `self.as_payload_ptr` returns a non-null ptr | ||
unsafe { Self::new_unchecked(slice::from_raw_parts(sample.as_payload_ptr(), len)) } | ||
} | ||
|
||
#[must_use] | ||
#[inline] | ||
pub fn len(self) -> usize { | ||
// SAFETY: `self.as_payload_ptr` returns a non-null ptr | ||
unsafe { (*self.as_payload_ptr()).len() } | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Clone for RawSample<T> { | ||
#[inline(always)] | ||
fn clone(&self) -> Self { | ||
*self | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Copy for RawSample<T> {} | ||
|
||
impl<T: ?Sized> fmt::Debug for RawSample<T> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
fmt::Pointer::fmt(&self.as_payload_ptr(), f) | ||
} | ||
} | ||
|
||
impl<T: ?Sized> fmt::Pointer for RawSample<T> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
fmt::Pointer::fmt(&self.as_payload_ptr(), f) | ||
} | ||
} | ||
|
||
#[repr(transparent)] | ||
pub struct RawSampleMut<T: ?Sized> { | ||
payload: *mut T, | ||
} | ||
|
||
impl<T: ?Sized> RawSampleMut<T> { | ||
#[inline] | ||
pub unsafe fn new_unchecked(payload: *mut T) -> Self { | ||
debug_assert!( | ||
!payload.is_null(), | ||
"RawSampleMut::new_unchecked requires that the payload pointer is non-null" | ||
); | ||
Self { payload } | ||
} | ||
|
||
#[allow(clippy::not_unsafe_ptr_arg_deref)] // false positive | ||
#[inline] | ||
pub fn new(payload: *mut T) -> Option<Self> { | ||
if !payload.is_null() { | ||
// SAFETY: `payload` pointer is checked to be non-null | ||
Some(unsafe { Self::new_unchecked(payload) }) | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
#[must_use] | ||
#[inline] | ||
pub fn cast<U>(self) -> RawSampleMut<U> { | ||
// SAFETY: `self.as_payload_mut_ptr` returns a non-null ptr | ||
unsafe { RawSampleMut::new_unchecked(self.as_payload_mut_ptr().cast::<U>()) } | ||
} | ||
|
||
#[must_use] | ||
#[inline(always)] | ||
pub fn as_payload_ptr(self) -> *const T { | ||
self.as_payload_mut_ptr() | ||
} | ||
|
||
#[must_use] | ||
#[inline(always)] | ||
pub fn as_payload_mut_ptr(self) -> *mut T { | ||
self.payload | ||
} | ||
|
||
#[must_use] | ||
#[inline] | ||
pub fn chunk_header(&self) -> &ChunkHeader { | ||
unsafe { | ||
ChunkHeader::from_user_payload_unchecked(self.as_payload_ptr() as *const c_void) | ||
.expect("Valid chunk header from payload!") | ||
} | ||
} | ||
} | ||
|
||
impl<T> RawSampleMut<[T]> { | ||
#[must_use] | ||
#[inline] | ||
pub fn slice_from_raw_parts(sample: RawSampleMut<T>, len: usize) -> RawSampleMut<[T]> { | ||
// SAFETY: `self.as_payload_mut_ptr` returns a non-null ptr | ||
unsafe { Self::new_unchecked(slice::from_raw_parts_mut(sample.as_payload_mut_ptr(), len)) } | ||
} | ||
|
||
#[must_use] | ||
#[inline] | ||
pub fn len(self) -> usize { | ||
// SAFETY: `self.as_payload_ptr` returns a non-null ptr | ||
unsafe { (*self.as_payload_ptr()).len() } | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Clone for RawSampleMut<T> { | ||
#[inline(always)] | ||
fn clone(&self) -> Self { | ||
*self | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Copy for RawSampleMut<T> {} | ||
|
||
impl<T: ?Sized> fmt::Debug for RawSampleMut<T> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
fmt::Pointer::fmt(&self.as_payload_ptr(), f) | ||
} | ||
} | ||
|
||
impl<T: ?Sized> fmt::Pointer for RawSampleMut<T> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
fmt::Pointer::fmt(&self.as_payload_ptr(), f) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.