use super::*;
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct TxStreamFormatEntry {
pub iso_channel: i8,
pub pcm: u32,
pub midi: u32,
pub speed: u32,
pub labels: Vec<String>,
pub iec60958: [Iec60958Param; IEC60958_CHANNELS],
}
const MIN_SIZE: usize = 272;
fn serialize_tx_stream_entry(entry: &TxStreamFormatEntry, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= MIN_SIZE);
serialize_i32(&(entry.iso_channel as i32), &mut raw[..4]);
serialize_u32(&entry.pcm, &mut raw[4..8]);
serialize_u32(&entry.midi, &mut raw[8..12]);
serialize_u32(&entry.speed, &mut raw[12..16]);
serialize_labels(&entry.labels, &mut raw[16..272])?;
if raw.len() >= 272 {
serialize_iec60958_params(&entry.iec60958, &mut raw[272..280])?;
}
Ok(())
}
fn deserialize_tx_stream_entry(entry: &mut TxStreamFormatEntry, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= MIN_SIZE);
let mut val = 0i32;
deserialize_i32(&mut val, &raw[..4]);
entry.iso_channel = val as i8;
deserialize_u32(&mut entry.pcm, &raw[4..8]);
deserialize_u32(&mut entry.midi, &raw[8..12]);
deserialize_u32(&mut entry.speed, &raw[12..16]);
deserialize_labels(&mut entry.labels, &raw[16..272])?;
if raw.len() >= MIN_SIZE {
deserialize_iec60958_params(&mut entry.iec60958, &raw[272..280])?;
}
Ok(())
}
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct TxStreamFormatParameters(pub Vec<TxStreamFormatEntry>);
impl<O: TcatOperation> TcatSectionSerdes<TxStreamFormatParameters> for O {
const MIN_SIZE: usize = 8;
const ERROR_TYPE: GeneralProtocolError = GeneralProtocolError::TxStreamFormat;
fn serialize(params: &TxStreamFormatParameters, raw: &mut [u8]) -> Result<(), String> {
let mut val = 0u32;
deserialize_u32(&mut val, &raw[..4]);
let count = val as usize;
if count != params.0.len() {
Err(format!(
"The count of entries should be {}, actually {}",
count,
params.0.len(),
))?;
}
deserialize_u32(&mut val, &raw[4..8]);
let size = 4 * val as usize;
let expected = 8 + size * count;
if raw.len() < expected {
let msg = format!(
"The size of buffer should be greater than {}, actually {}",
expected,
raw.len()
);
Err(msg)?;
}
params.0.iter().enumerate().try_for_each(|(i, entry)| {
let pos = 8 + size * i;
serialize_tx_stream_entry(entry, &mut raw[pos..(pos + size)])
})
}
fn deserialize(params: &mut TxStreamFormatParameters, raw: &[u8]) -> Result<(), String> {
let mut val = 0u32;
deserialize_u32(&mut val, &raw[..4]);
let count = val as usize;
deserialize_u32(&mut val, &raw[4..8]);
let size = 4 * val as usize;
let expected = 8 + size * count;
if raw.len() < expected {
let msg = format!(
"The size of buffer should be greater than {}, actually {}",
expected,
raw.len()
);
Err(msg)?;
}
params.0.resize_with(count, Default::default);
params.0.iter_mut().enumerate().try_for_each(|(i, entry)| {
let pos = 8 + size * i;
deserialize_tx_stream_entry(entry, &raw[pos..(pos + size)])
})
}
}
impl<O: TcatOperation> TcatSectionOperation<TxStreamFormatParameters> for O {}
impl<O: TcatSectionOperation<TxStreamFormatParameters>>
TcatMutableSectionOperation<TxStreamFormatParameters> for O
{
}
impl<O: TcatSectionOperation<TxStreamFormatParameters>>
TcatNotifiedSectionOperation<TxStreamFormatParameters> for O
{
const NOTIFY_FLAG: u32 = NOTIFY_TX_CFG_CHG;
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn tx_stream_format_params_serdes() {
let params = TxStreamFormatEntry {
iso_channel: 32,
pcm: 4,
midi: 2,
speed: 4,
labels: vec![
"a".to_string(),
"b".to_string(),
"c".to_string(),
"d".to_string(),
],
iec60958: [Iec60958Param {
cap: true,
enable: false,
}; IEC60958_CHANNELS],
};
let mut raw = [0u8; 2048];
serialize_tx_stream_entry(¶ms, &mut raw).unwrap();
let mut p = TxStreamFormatEntry::default();
deserialize_tx_stream_entry(&mut p, &raw).unwrap();
assert_eq!(params, p);
}
}