pub use self::store_array::StoreArray;
mod store_array;
pub use self::store_struct::StoreStruct;
mod store_struct;
pub use self::store_variant::StoreVariant;
mod store_variant;
pub use self::raw::{Raw, RawArray};
mod raw;
#[cfg(test)]
mod tests;
use core::fmt;
use alloc::borrow::ToOwned;
use crate::arguments::Arguments;
use crate::buf::{AlignedBuf, Alloc};
use crate::error::Result;
use crate::signature::{SignatureBuilder, SignatureError};
use crate::ty;
use crate::{Body, Endianness, Frame, Signature, SignatureBuf, Storable, Write, WriteAligned};
#[derive(Clone, PartialEq, Eq)]
pub struct BodyBuf {
buf: AlignedBuf,
endianness: Endianness,
signature: SignatureBuilder,
}
impl BodyBuf {
pub fn new() -> Self {
Self::with_endianness(Endianness::NATIVE)
}
pub(crate) fn from_raw_parts(
buf: AlignedBuf,
endianness: Endianness,
signature: SignatureBuf,
) -> Self {
Self {
buf,
endianness,
signature: SignatureBuilder::from_owned_signature(signature),
}
}
pub fn with_endianness(endianness: Endianness) -> Self {
Self {
signature: SignatureBuilder::new(),
endianness,
buf: AlignedBuf::new(),
}
}
pub fn clear(&mut self) {
self.signature.clear();
self.buf.clear();
}
pub fn signature(&self) -> &Signature {
&self.signature
}
pub fn endianness(&self) -> Endianness {
self.endianness
}
#[inline]
pub fn is_empty(&self) -> bool {
self.buf.is_empty()
}
#[inline]
pub fn len(&self) -> usize {
self.buf.len()
}
#[inline]
pub(crate) fn align_mut<T>(&mut self) {
self.buf.align_mut::<T>();
}
#[inline]
pub(crate) fn align_mut_to(&mut self, align: usize) {
self.buf.align_mut_to(align);
}
#[inline]
pub fn get(&self) -> &[u8] {
self.buf.get()
}
#[inline]
pub fn as_body(&self) -> Body<'_> {
let data = self.buf.as_aligned();
Body::from_raw_parts(data, self.endianness, &self.signature)
}
#[inline]
pub(crate) fn alloc<T>(&mut self) -> Alloc<T>
where
T: Frame,
{
self.buf.alloc()
}
#[inline]
pub(crate) fn store_at<T>(&mut self, at: Alloc<T>, mut frame: T)
where
T: Frame,
{
frame.adjust(self.endianness);
self.buf.store_at(at, frame);
}
pub fn store<T>(&mut self, frame: T) -> Result<()>
where
T: Storable,
{
if !T::write_signature(&mut self.signature) {
return Err(SignatureError::too_long().into());
}
frame.store_to(self);
Ok(())
}
pub(crate) fn store_frame<T>(&mut self, mut frame: T)
where
T: Frame,
{
frame.adjust(self.endianness);
self.buf.store(frame);
}
pub(crate) fn extend_from_slice(&mut self, bytes: &[u8]) {
self.buf.extend_from_slice(bytes);
}
pub(crate) fn extend_from_slice_nul(&mut self, bytes: &[u8]) {
self.buf.extend_from_slice_nul(bytes);
}
pub(crate) fn write_only<T>(&mut self, value: &T)
where
T: ?Sized + Write,
{
value.write_to(self);
}
#[inline]
pub fn arguments<T>(&mut self, value: T) -> Result<()>
where
T: Arguments,
{
value.extend_to(self)
}
pub fn store_array<E>(&mut self) -> Result<StoreArray<'_, E>>
where
E: ty::Marker,
{
<ty::Array<E> as ty::Marker>::write_signature(&mut self.signature)?;
Ok(StoreArray::new(self))
}
pub fn write_slice(&mut self, data: &[u8]) -> Result<()> {
self.store_array::<u8>()?.write_slice(data);
Ok(())
}
pub fn store_struct<E>(&mut self) -> Result<StoreStruct<'_, E>>
where
E: ty::Fields,
{
E::write_signature(&mut self.signature)?;
Ok(StoreStruct::new(self))
}
pub fn store_variant(&mut self, signature: &Signature) -> Result<StoreVariant<'_>> {
if !self.signature.extend_from_signature(Signature::VARIANT) {
return Err(SignatureError::too_long().into());
}
Ok(StoreVariant::new(self, signature))
}
pub fn store_raw(&mut self, signature: &Signature) -> Result<Raw<'_>> {
self.extend_signature(signature)?;
Ok(Raw::new(self))
}
pub fn extend_signature(&mut self, signature: &Signature) -> Result<()> {
if !self.signature.extend_from_signature(signature) {
return Err(SignatureError::too_long().into());
}
Ok(())
}
#[inline]
pub fn raw(&mut self) -> Raw<'_> {
Raw::new(self)
}
}
impl fmt::Debug for BodyBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BodyBuf")
.field("buf", &self.buf)
.field("endianness", &self.endianness)
.field("signature", &self.signature.to_signature())
.finish()
}
}
impl Default for BodyBuf {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl From<Body<'_>> for BodyBuf {
#[inline]
fn from(buf: Body<'_>) -> Self {
let (buf, endianness, signature) = buf.into_raw_parts();
let buf = AlignedBuf::from(buf);
let signature = signature.to_owned();
Self::from_raw_parts(buf, endianness, signature)
}
}
impl WriteAligned for BodyBuf {
#[inline]
fn write_only<T>(&mut self, value: &T)
where
T: ?Sized + Write,
{
BodyBuf::write_only(self, value);
}
#[inline]
fn store<T>(&mut self, frame: T) -> Result<()>
where
T: Storable,
{
BodyBuf::store(self, frame)
}
#[inline]
fn store_frame<T>(&mut self, frame: T)
where
T: Frame,
{
BodyBuf::store_frame(self, frame);
}
#[inline]
fn extend_from_slice(&mut self, bytes: &[u8]) {
BodyBuf::extend_from_slice(self, bytes);
}
#[inline]
fn extend_from_slice_nul(&mut self, bytes: &[u8]) {
BodyBuf::extend_from_slice_nul(self, bytes);
}
}