dvb_si/descriptors/
multiplex_buffer_utilization.rs1use super::descriptor_body;
7use crate::error::{Error, Result};
8use dvb_common::{Parse, Serialize};
9
10pub const TAG: u8 = 0x0C;
12const HEADER_LEN: usize = 2;
13const BODY_LEN: u8 = 4;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
18#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
19pub struct MultiplexBufferUtilizationDescriptor {
20 pub bound_valid_flag: bool,
22 pub ltw_offset_lower_bound: u16,
24 pub ltw_offset_upper_bound: u16,
26}
27
28impl<'a> Parse<'a> for MultiplexBufferUtilizationDescriptor {
29 type Error = crate::error::Error;
30
31 fn parse(bytes: &'a [u8]) -> Result<Self> {
32 let body = descriptor_body(
33 bytes,
34 TAG,
35 "MultiplexBufferUtilizationDescriptor",
36 "unexpected tag for multiplex_buffer_utilization_descriptor",
37 )?;
38 if body.len() != BODY_LEN as usize {
39 return Err(Error::InvalidDescriptor {
40 tag: TAG,
41 reason: "multiplex_buffer_utilization_descriptor length must equal 4",
42 });
43 }
44 let bound_valid_flag = (body[0] & 0x80) != 0;
45 let ltw_offset_lower_bound = ((u16::from(body[0]) & 0x7F) << 8) | u16::from(body[1]);
46 let ltw_offset_upper_bound = ((u16::from(body[2]) & 0x7F) << 8) | u16::from(body[3]);
47 Ok(Self {
48 bound_valid_flag,
49 ltw_offset_lower_bound,
50 ltw_offset_upper_bound,
51 })
52 }
53}
54
55impl Serialize for MultiplexBufferUtilizationDescriptor {
56 type Error = crate::error::Error;
57
58 fn serialized_len(&self) -> usize {
59 HEADER_LEN + (BODY_LEN as usize)
60 }
61
62 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
63 let len = self.serialized_len();
64 if buf.len() < len {
65 return Err(Error::OutputBufferTooSmall {
66 need: len,
67 have: buf.len(),
68 });
69 }
70 buf[0] = TAG;
71 buf[1] = BODY_LEN;
72 buf[HEADER_LEN] = ((self.bound_valid_flag as u8) << 7)
73 | ((self.ltw_offset_lower_bound >> 8) as u8 & 0x7F);
74 buf[HEADER_LEN + 1] = (self.ltw_offset_lower_bound & 0xFF) as u8;
75 buf[HEADER_LEN + 2] = (self.ltw_offset_upper_bound >> 8) as u8 & 0x7F;
76 buf[HEADER_LEN + 3] = (self.ltw_offset_upper_bound & 0xFF) as u8;
77 Ok(len)
78 }
79}
80impl<'a> crate::traits::DescriptorDef<'a> for MultiplexBufferUtilizationDescriptor {
81 const TAG: u8 = TAG;
82 const NAME: &'static str = "MULTIPLEX_BUFFER_UTILIZATION";
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn parse() {
91 let bytes = [
92 TAG,
93 4,
94 0b1_1111111,
95 0xAB, 0b1_1111111,
97 0xCD, ];
99 let d = MultiplexBufferUtilizationDescriptor::parse(&bytes).unwrap();
100 assert!(d.bound_valid_flag);
101 assert_eq!(d.ltw_offset_lower_bound, 0x7FAB);
102 assert_eq!(d.ltw_offset_upper_bound, 0x7FCD);
103 }
104
105 #[test]
106 fn serialize_round_trip() {
107 let d = MultiplexBufferUtilizationDescriptor {
108 bound_valid_flag: false,
109 ltw_offset_lower_bound: 0x1234,
110 ltw_offset_upper_bound: 0x5678,
111 };
112 let mut buf = vec![0u8; d.serialized_len()];
113 d.serialize_into(&mut buf).unwrap();
114 let reparsed = MultiplexBufferUtilizationDescriptor::parse(&buf).unwrap();
115 assert_eq!(d, reparsed);
116 }
117
118 #[test]
119 fn parse_rejects_wrong_tag() {
120 let err = MultiplexBufferUtilizationDescriptor::parse(&[0x0D, 4, 0, 0, 0, 0]).unwrap_err();
121 assert!(matches!(err, Error::InvalidDescriptor { tag: 0x0D, .. }));
122 }
123
124 #[test]
125 fn parse_rejects_wrong_length() {
126 let err = MultiplexBufferUtilizationDescriptor::parse(&[TAG, 3, 0, 0, 0]).unwrap_err();
127 assert!(matches!(err, Error::InvalidDescriptor { tag: TAG, .. }));
128 }
129
130 #[test]
131 fn serialize_rejects_small_buffer() {
132 let d = MultiplexBufferUtilizationDescriptor {
133 bound_valid_flag: false,
134 ltw_offset_lower_bound: 0,
135 ltw_offset_upper_bound: 0,
136 };
137 let mut tiny = vec![0u8; 3];
138 let err = d.serialize_into(&mut tiny).unwrap_err();
139 assert!(matches!(err, Error::OutputBufferTooSmall { .. }));
140 }
141}