dvb_si/descriptors/ait/
simple_application_boundary.rs1use crate::descriptors::descriptor_body;
8use crate::error::{Error, Result};
9use alloc::vec::Vec;
10use dvb_common::{Parse, Serialize};
11
12pub const TAG: u8 = 0x17;
14const HEADER_LEN: usize = 2;
15const COUNT_LEN: usize = 1;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize))]
20pub struct SimpleApplicationBoundaryDescriptor<'a> {
21 #[cfg_attr(feature = "serde", serde(borrow))]
23 pub boundary_extensions: Vec<&'a [u8]>,
24}
25
26impl<'a> Parse<'a> for SimpleApplicationBoundaryDescriptor<'a> {
27 type Error = crate::error::Error;
28 fn parse(bytes: &'a [u8]) -> Result<Self> {
29 let body = descriptor_body(
30 bytes,
31 TAG,
32 "SimpleApplicationBoundaryDescriptor",
33 "unexpected tag for simple_application_boundary_descriptor",
34 )?;
35 if body.is_empty() {
36 return Err(Error::InvalidDescriptor {
37 tag: TAG,
38 reason: "simple_application_boundary_descriptor body is empty",
39 });
40 }
41 let boundary_extension_count = body[0] as usize;
42 let mut extensions = Vec::with_capacity(boundary_extension_count);
43 let mut pos = COUNT_LEN;
44 for _ in 0..boundary_extension_count {
45 if pos >= body.len() {
46 return Err(Error::InvalidDescriptor {
47 tag: TAG,
48 reason: "boundary_extension_length missing",
49 });
50 }
51 let ext_len = body[pos] as usize;
52 pos += 1;
53 let ext_end = pos + ext_len;
54 if ext_end > body.len() {
55 return Err(Error::InvalidDescriptor {
56 tag: TAG,
57 reason: "boundary_extension bytes run past descriptor end",
58 });
59 }
60 extensions.push(&body[pos..ext_end]);
61 pos = ext_end;
62 }
63 Ok(Self {
64 boundary_extensions: extensions,
65 })
66 }
67}
68
69impl Serialize for SimpleApplicationBoundaryDescriptor<'_> {
70 type Error = crate::error::Error;
71 fn serialized_len(&self) -> usize {
72 HEADER_LEN
73 + COUNT_LEN
74 + self
75 .boundary_extensions
76 .iter()
77 .map(|e| 1 + e.len())
78 .sum::<usize>()
79 }
80
81 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
82 for e in &self.boundary_extensions {
83 if e.len() > u8::MAX as usize {
84 return Err(Error::InvalidDescriptor {
85 tag: TAG,
86 reason: "boundary_extension exceeds 255 bytes",
87 });
88 }
89 }
90 let len = self.serialized_len();
91 let body_len = len - HEADER_LEN;
92 if body_len > u8::MAX as usize {
93 return Err(Error::InvalidDescriptor {
94 tag: TAG,
95 reason: "simple_application_boundary_descriptor body exceeds 255 bytes",
96 });
97 }
98 if buf.len() < len {
99 return Err(Error::OutputBufferTooSmall {
100 need: len,
101 have: buf.len(),
102 });
103 }
104 buf[0] = TAG;
105 buf[1] = body_len as u8;
106 buf[2] = self.boundary_extensions.len() as u8;
107 let mut pos = HEADER_LEN + COUNT_LEN;
108 for e in &self.boundary_extensions {
109 buf[pos] = e.len() as u8;
110 buf[pos + 1..pos + 1 + e.len()].copy_from_slice(e);
111 pos += 1 + e.len();
112 }
113 Ok(len)
114 }
115}
116
117impl<'a> crate::traits::DescriptorDef<'a> for SimpleApplicationBoundaryDescriptor<'a> {
118 const TAG: u8 = TAG;
119 const NAME: &'static str = "SIMPLE_APPLICATION_BOUNDARY";
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 fn build_two_extensions() -> [u8; 10] {
128 [
129 TAG, 8, 2, 3, b'f', b'o', b'o', 2, b'b', b'a',
131 ]
132 }
133
134 #[test]
135 fn parse_two_extensions() {
136 let bytes = build_two_extensions();
137 let d = SimpleApplicationBoundaryDescriptor::parse(&bytes).unwrap();
138 assert_eq!(d.boundary_extensions.len(), 2);
139 assert_eq!(d.boundary_extensions[0], b"foo");
140 assert_eq!(d.boundary_extensions[1], b"ba");
141 }
142
143 #[test]
144 fn parse_no_extensions() {
145 let bytes = [TAG, 1, 0];
146 let d = SimpleApplicationBoundaryDescriptor::parse(&bytes).unwrap();
147 assert!(d.boundary_extensions.is_empty());
148 }
149
150 #[test]
151 fn serialize_round_trip() {
152 let d = SimpleApplicationBoundaryDescriptor {
153 boundary_extensions: alloc::vec![b"abc" as &[u8], b"de" as &[u8]],
154 };
155 let mut buf = vec![0u8; d.serialized_len()];
156 d.serialize_into(&mut buf).unwrap();
157 let re = SimpleApplicationBoundaryDescriptor::parse(&buf).unwrap();
158 assert_eq!(d, re);
159 }
160
161 #[test]
162 fn serialize_byte_identical() {
163 let bytes = build_two_extensions();
164 let d = SimpleApplicationBoundaryDescriptor::parse(&bytes).unwrap();
165 let mut buf = vec![0u8; d.serialized_len()];
166 d.serialize_into(&mut buf).unwrap();
167 assert_eq!(buf.as_slice(), &bytes[..]);
168 }
169}