use crate::protocol::{
self, ReadBytes, ReadBytesExt, ReadFromBytes, SizeBytes, WriteBytes, WriteBytesExt,
WriteToBytes, LE,
};
use std::borrow::Cow;
use std::ffi::CString;
use std::{io, mem};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Header {
pub citp_header: protocol::Header,
pub content_type: u32,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Message<T> {
pub finf_header: Header,
pub message: T,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SFra<'a> {
pub fixture_identifiers: Cow<'a, [u16]>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Fram {
pub fixture_identifier: u16,
pub frame_filter_count: u8,
pub frame_gobo_count: u8,
pub frame_names: CString,
}
impl Header {
pub const CONTENT_TYPE: &'static [u8; 4] = b"FINF";
}
impl<'a> SFra<'a> {
pub const CONTENT_TYPE: &'static [u8; 4] = b"SFra";
}
impl Fram {
pub const CONTENT_TYPE: &'static [u8; 4] = b"Fram";
}
impl WriteToBytes for Header {
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_bytes(self.citp_header)?;
writer.write_u32::<LE>(self.content_type)?;
Ok(())
}
}
impl<T> WriteToBytes for Message<T>
where
T: WriteToBytes,
{
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_bytes(self.finf_header)?;
writer.write_bytes(&self.message)?;
Ok(())
}
}
impl<'a> WriteToBytes for SFra<'a> {
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_u16::<LE>(self.fixture_identifiers.len() as _)?;
for &id in self.fixture_identifiers.iter() {
writer.write_u16::<LE>(id)?;
}
Ok(())
}
}
impl WriteToBytes for Fram {
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_u16::<LE>(self.fixture_identifier)?;
writer.write_u8(self.frame_filter_count)?;
writer.write_u8(self.frame_gobo_count)?;
writer.write_bytes(&self.frame_names)?;
Ok(())
}
}
impl ReadFromBytes for SFra<'static> {
fn read_from_bytes<R: ReadBytesExt>(mut reader: R) -> io::Result<Self> {
let fixture_count = reader.read_u16::<LE>()?;
let fixture_identifiers = protocol::read_new_vec(reader, fixture_count as _)?;
let fixture_identifiers = Cow::Owned(fixture_identifiers);
let sfra = SFra {
fixture_identifiers,
};
Ok(sfra)
}
}
impl ReadFromBytes for Fram {
fn read_from_bytes<R: ReadBytesExt>(mut reader: R) -> io::Result<Self> {
let fixture_identifier = reader.read_u16::<LE>()?;
let frame_filter_count = reader.read_u8()?;
let frame_gobo_count = reader.read_u8()?;
let frame_names = reader.read_bytes()?;
let fram = Fram {
fixture_identifier,
frame_filter_count,
frame_gobo_count,
frame_names,
};
Ok(fram)
}
}
impl<'a> SizeBytes for SFra<'a> {
fn size_bytes(&self) -> usize {
mem::size_of::<u16>() + self.fixture_identifiers.len() * mem::size_of::<u16>()
}
}
impl SizeBytes for Fram {
fn size_bytes(&self) -> usize {
mem::size_of::<u16>()
+ mem::size_of::<u8>()
+ mem::size_of::<u8>()
+ self.frame_names.size_bytes()
}
}