firewire_dice_protocols/tcat/
tx_stream_format_section.rs1use super::*;
9
10#[derive(Default, Debug, Clone, PartialEq, Eq)]
12pub struct TxStreamFormatEntry {
13 pub iso_channel: i8,
15 pub pcm: u32,
17 pub midi: u32,
19 pub speed: u32,
21 pub labels: Vec<String>,
23 pub iec60958: [Iec60958Param; IEC60958_CHANNELS],
25}
26
27const MIN_SIZE: usize = 272;
28
29fn serialize_tx_stream_entry(entry: &TxStreamFormatEntry, raw: &mut [u8]) -> Result<(), String> {
30 assert!(raw.len() >= MIN_SIZE);
31
32 serialize_i32(&(entry.iso_channel as i32), &mut raw[..4]);
33
34 serialize_u32(&entry.pcm, &mut raw[4..8]);
35 serialize_u32(&entry.midi, &mut raw[8..12]);
36 serialize_u32(&entry.speed, &mut raw[12..16]);
37
38 serialize_labels(&entry.labels, &mut raw[16..272])?;
39
40 if raw.len() >= 272 {
42 serialize_iec60958_params(&entry.iec60958, &mut raw[272..280])?;
43 }
44
45 Ok(())
46}
47
48fn deserialize_tx_stream_entry(entry: &mut TxStreamFormatEntry, raw: &[u8]) -> Result<(), String> {
49 assert!(raw.len() >= MIN_SIZE);
50
51 let mut val = 0i32;
52 deserialize_i32(&mut val, &raw[..4]);
53 entry.iso_channel = val as i8;
54
55 deserialize_u32(&mut entry.pcm, &raw[4..8]);
56 deserialize_u32(&mut entry.midi, &raw[8..12]);
57 deserialize_u32(&mut entry.speed, &raw[12..16]);
58
59 deserialize_labels(&mut entry.labels, &raw[16..272])?;
60
61 if raw.len() >= MIN_SIZE {
63 deserialize_iec60958_params(&mut entry.iec60958, &raw[272..280])?;
64 }
65
66 Ok(())
67}
68
69#[derive(Default, Debug, Clone, PartialEq, Eq)]
71pub struct TxStreamFormatParameters(pub Vec<TxStreamFormatEntry>);
72
73impl<O: TcatOperation> TcatSectionSerdes<TxStreamFormatParameters> for O {
74 const MIN_SIZE: usize = 8;
75
76 const ERROR_TYPE: GeneralProtocolError = GeneralProtocolError::TxStreamFormat;
77
78 fn serialize(params: &TxStreamFormatParameters, raw: &mut [u8]) -> Result<(), String> {
79 let mut val = 0u32;
80
81 deserialize_u32(&mut val, &raw[..4]);
83 let count = val as usize;
84
85 if count != params.0.len() {
86 Err(format!(
87 "The count of entries should be {}, actually {}",
88 count,
89 params.0.len(),
90 ))?;
91 }
92
93 deserialize_u32(&mut val, &raw[4..8]);
95 let size = 4 * val as usize;
96
97 let expected = 8 + size * count;
98 if raw.len() < expected {
99 let msg = format!(
100 "The size of buffer should be greater than {}, actually {}",
101 expected,
102 raw.len()
103 );
104 Err(msg)?;
105 }
106
107 params.0.iter().enumerate().try_for_each(|(i, entry)| {
108 let pos = 8 + size * i;
109 serialize_tx_stream_entry(entry, &mut raw[pos..(pos + size)])
110 })
111 }
112
113 fn deserialize(params: &mut TxStreamFormatParameters, raw: &[u8]) -> Result<(), String> {
114 let mut val = 0u32;
115 deserialize_u32(&mut val, &raw[..4]);
116 let count = val as usize;
117
118 deserialize_u32(&mut val, &raw[4..8]);
119 let size = 4 * val as usize;
120
121 let expected = 8 + size * count;
122 if raw.len() < expected {
123 let msg = format!(
124 "The size of buffer should be greater than {}, actually {}",
125 expected,
126 raw.len()
127 );
128 Err(msg)?;
129 }
130
131 params.0.resize_with(count, Default::default);
132
133 params.0.iter_mut().enumerate().try_for_each(|(i, entry)| {
134 let pos = 8 + size * i;
135 deserialize_tx_stream_entry(entry, &raw[pos..(pos + size)])
136 })
137 }
138}
139
140impl<O: TcatOperation> TcatSectionOperation<TxStreamFormatParameters> for O {}
141
142impl<O: TcatSectionOperation<TxStreamFormatParameters>>
143 TcatMutableSectionOperation<TxStreamFormatParameters> for O
144{
145}
146
147impl<O: TcatSectionOperation<TxStreamFormatParameters>>
148 TcatNotifiedSectionOperation<TxStreamFormatParameters> for O
149{
150 const NOTIFY_FLAG: u32 = NOTIFY_TX_CFG_CHG;
151}
152
153#[cfg(test)]
154mod test {
155 use super::*;
156
157 #[test]
158 fn tx_stream_format_params_serdes() {
159 let params = TxStreamFormatEntry {
160 iso_channel: 32,
161 pcm: 4,
162 midi: 2,
163 speed: 4,
164 labels: vec![
165 "a".to_string(),
166 "b".to_string(),
167 "c".to_string(),
168 "d".to_string(),
169 ],
170 iec60958: [Iec60958Param {
171 cap: true,
172 enable: false,
173 }; IEC60958_CHANNELS],
174 };
175 let mut raw = [0u8; 2048];
176 serialize_tx_stream_entry(¶ms, &mut raw).unwrap();
177
178 let mut p = TxStreamFormatEntry::default();
179 deserialize_tx_stream_entry(&mut p, &raw).unwrap();
180
181 assert_eq!(params, p);
182 }
183}