diff --git a/core/src/bbbuffer.rs b/core/src/bbbuffer.rs index 1492a55..54c0508 100644 --- a/core/src/bbbuffer.rs +++ b/core/src/bbbuffer.rs @@ -100,16 +100,7 @@ impl<'a, const N: usize> BBBuffer { let nn1 = NonNull::new_unchecked(self as *const _ as *mut _); let nn2 = NonNull::new_unchecked(self as *const _ as *mut _); - Ok(( - Producer { - bbq: nn1, - pd: PhantomData, - }, - Consumer { - bbq: nn2, - pd: PhantomData, - }, - )) + Ok((Producer::new_unchecked(nn1), Consumer::new_unchecked(nn2))) } } @@ -127,7 +118,12 @@ impl<'a, const N: usize> BBBuffer { /// section while splitting. pub fn try_split_framed(&'a self) -> Result<(FrameProducer<'a, N>, FrameConsumer<'a, N>)> { let (producer, consumer) = self.try_split()?; - Ok((FrameProducer { producer }, FrameConsumer { consumer })) + unsafe { + Ok(( + FrameProducer::new_unchecked(producer), + FrameConsumer::new_unchecked(consumer), + )) + } } /// Attempt to release the Producer and Consumer @@ -313,6 +309,21 @@ pub struct Producer<'a, const N: usize> { unsafe impl<'a, const N: usize> Send for Producer<'a, N> {} impl<'a, const N: usize> Producer<'a, N> { + /// Create a `Producer` from a non null pointer to a [`BBBuffer`]. + /// + /// # Safety + /// + /// The caller must ensure the [`BBBuffer`] was previously initialized. See + /// [`BBBUffer::try_split`] + /// + /// [`BBBuffer`]: crate::BBBuffer + /// [`BBBuffer::try_split`]: crate::BBBuffer::try_split + pub unsafe fn new_unchecked(bbq: NonNull>) -> Self { + Self { + bbq, + pd: PhantomData, + } + } /// Request a writable, contiguous section of memory of exactly /// `sz` bytes. If the buffer size requested is not available, /// an error will be returned. @@ -518,6 +529,21 @@ pub struct Consumer<'a, const N: usize> { unsafe impl<'a, const N: usize> Send for Consumer<'a, N> {} impl<'a, const N: usize> Consumer<'a, N> { + /// Create a `Consumer` from a non null pointer to a [`BBBuffer`]. + /// + /// # Safety + /// + /// The caller must ensure the [`BBBuffer`] was previously initialized. See + /// [`BBBUffer::try_split`] + /// + /// [`BBBuffer`]: crate::BBBuffer + /// [`BBBuffer::try_split`]: crate::BBBuffer::try_split + pub unsafe fn new_unchecked(bbq: NonNull>) -> Self { + Self { + bbq, + pd: PhantomData, + } + } /// Obtains a contiguous slice of committed bytes. This slice may not /// contain ALL available bytes, if the writer has wrapped around. The /// remaining bytes will be available after all readable bytes are diff --git a/core/src/framed.rs b/core/src/framed.rs index f0d4449..d878cbe 100644 --- a/core/src/framed.rs +++ b/core/src/framed.rs @@ -88,6 +88,18 @@ pub struct FrameProducer<'a, const N: usize> { } impl<'a, const N: usize> FrameProducer<'a, N> { + /// Create a `FrameProducer` from a non null pointer to a [`BBBuffer`]. + /// + /// # Safety + /// + /// The caller must ensure the [`BBBuffer`] was previously initialized. See + /// [`BBBUffer::try_split_framed`] + /// + /// [`BBBuffer`]: crate::BBBuffer + /// [`BBBuffer::try_split_framed`]: crate::BBBuffer::try_split_framed + pub unsafe fn new_unchecked(producer: Producer<'a, N>) -> Self { + Self { producer } + } /// Receive a grant for a frame with a maximum size of `max_sz` in bytes. /// /// This size does not include the size of the frame header. The exact size @@ -107,6 +119,18 @@ pub struct FrameConsumer<'a, const N: usize> { } impl<'a, const N: usize> FrameConsumer<'a, N> { + /// Create a `FrameConsumer` from a non null pointer to a [`BBBuffer`]. + /// + /// # Safety + /// + /// The caller must ensure the [`BBBuffer`] was previously initialized. See + /// [`BBBUffer::try_split_framed`] + /// + /// [`BBBuffer`]: crate::BBBuffer + /// [`BBBuffer::try_split_framed`]: crate::BBBuffer::try_split_framed + pub unsafe fn new_unchecked(consumer: Consumer<'a, N>) -> Self { + Self { consumer } + } /// Obtain the next available frame, if any pub fn read(&mut self) -> Option> { // Get all available bytes. We never wrap a frame around,