use crate::payload::number_of_elements;
use crate::port::details::chunk::ChunkMut;
use crate::port::details::chunk_mut_shared_state::ChunkMutSharedState;
use crate::service::header::payload_header::PayloadHeader;
use crate::service::marker::Flatbuffer;
use crate::{
port::SendError, port::publisher::PublisherSharedState,
service::header::publish_subscribe::Header,
};
use flatbuffers::InvalidFlatbuffer;
use iceoryx2_bb_elementary_traits::iceoryx_send::IceoryxSend;
use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend;
use iceoryx2_bb_flatbuffers::FlatbufferError;
use core::fmt::{Debug, Formatter};
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
pub struct SampleMut<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ?Sized,
UserHeader: ZeroCopySend,
> {
pub(crate) shared_state: ChunkMutSharedState<Service, PublisherSharedState<Service>>,
pub(crate) chunk: ChunkMut,
pub(crate) _payload: PhantomData<Payload>,
pub(crate) _user_header: PhantomData<UserHeader>,
}
unsafe impl<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ?Sized,
UserHeader: ZeroCopySend,
> Send for SampleMut<Service, Payload, UserHeader>
where
Service::ArcThreadSafetyPolicy<PublisherSharedState<Service>>: Send + Sync,
{
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ZeroCopySend,
UserHeader: ZeroCopySend,
> Deref for SampleMut<Service, Payload, UserHeader>
{
type Target = Payload;
fn deref(&self) -> &Self::Target {
unsafe { &*self.chunk.payload_ptr().cast() }
}
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ZeroCopySend,
UserHeader: ZeroCopySend,
> Deref for SampleMut<Service, [Payload], UserHeader>
{
type Target = [Payload];
fn deref(&self) -> &Self::Target {
let payload_size = self.shared_state.payload_size();
unsafe {
&*core::ptr::slice_from_raw_parts(
self.chunk.payload_ptr().cast(),
number_of_elements::<Payload, _>(self.header(), payload_size),
)
}
}
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ZeroCopySend,
UserHeader: ZeroCopySend,
> DerefMut for SampleMut<Service, Payload, UserHeader>
{
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.chunk.payload_mut_ptr().cast() }
}
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ZeroCopySend,
UserHeader: ZeroCopySend,
> DerefMut for SampleMut<Service, [Payload], UserHeader>
{
fn deref_mut(&mut self) -> &mut Self::Target {
let payload_size = self.shared_state.payload_size();
unsafe {
&mut *core::ptr::slice_from_raw_parts_mut(
self.chunk.payload_mut_ptr().cast(),
number_of_elements::<Payload, _>(self.header(), payload_size),
)
}
}
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ?Sized,
UserHeader: ZeroCopySend,
> Debug for SampleMut<Service, Payload, UserHeader>
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(
f,
"SampleMut<{}, {}, {}> {{ shared_state: {:?}, chunk: {:?} }}",
core::any::type_name::<Service>(),
core::any::type_name::<Payload>(),
core::any::type_name::<UserHeader>(),
self.shared_state,
self.chunk
)
}
}
impl<Service: crate::service::Service, Payload: Debug, UserHeader: ZeroCopySend>
SampleMut<Service, Flatbuffer<Payload>, UserHeader>
{
pub fn payload_bytes(&self) -> &[u8] {
let payload_offset = self.header().payload_offset() as usize;
let payload_ptr = self.chunk.payload_ptr();
let payload_len = self.header().number_of_elements() as usize;
unsafe {
core::slice::from_raw_parts(
payload_ptr.add(payload_offset),
payload_len - payload_offset,
)
}
}
pub fn payload_root<'a>(&'a self) -> Result<Payload::Inner, FlatbufferError<InvalidFlatbuffer>>
where
Payload: flatbuffers::Follow<'a> + flatbuffers::Verifiable,
{
Ok(flatbuffers::root::<Payload>(self.payload_bytes())?)
}
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + Debug + ?Sized,
UserHeader: ZeroCopySend,
> SampleMut<Service, Payload, UserHeader>
{
pub fn header(&self) -> &Header {
unsafe { &*self.chunk.header_ptr().cast() }
}
pub fn user_header(&self) -> &UserHeader {
unsafe { &*self.chunk.user_header_ptr().cast() }
}
pub fn user_header_mut(&mut self) -> &mut UserHeader {
unsafe { &mut *self.chunk.user_header_mut_ptr().cast() }
}
pub fn send(self) -> Result<usize, SendError> {
self.shared_state
.call(|publisher_shared_state| publisher_shared_state.send_sample(&self.chunk))
}
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + ZeroCopySend + Debug,
UserHeader: ZeroCopySend,
> SampleMut<Service, Payload, UserHeader>
{
pub fn payload(&self) -> &Payload {
self.deref()
}
pub fn payload_mut(&mut self) -> &mut Payload {
&mut *self
}
}
impl<
Service: crate::service::Service,
Payload: IceoryxSend + ZeroCopySend + Debug,
UserHeader: ZeroCopySend,
> SampleMut<Service, [Payload], UserHeader>
{
pub fn payload(&self) -> &[Payload] {
self.deref()
}
pub fn payload_mut(&mut self) -> &mut [Payload] {
&mut *self
}
}