dvb_si/descriptors/ait/
dvb_j_application.rs1use crate::descriptors::descriptor_body;
8use crate::error::{Error, Result};
9use alloc::vec::Vec;
10use dvb_common::{Parse, Serialize};
11
12pub const TAG: u8 = 0x03;
14const HEADER_LEN: usize = 2;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize))]
19pub struct DvbJApplicationDescriptor<'a> {
20 #[cfg_attr(feature = "serde", serde(borrow))]
22 pub parameters: Vec<&'a [u8]>,
23}
24
25impl<'a> Parse<'a> for DvbJApplicationDescriptor<'a> {
26 type Error = crate::error::Error;
27 fn parse(bytes: &'a [u8]) -> Result<Self> {
28 let body = descriptor_body(
29 bytes,
30 TAG,
31 "DvbJApplicationDescriptor",
32 "unexpected tag for dvb_j_application_descriptor",
33 )?;
34 let mut parameters = Vec::new();
35 let mut pos = 0;
36 while pos < body.len() {
37 let param_len = body[pos] as usize;
38 pos += 1;
39 if pos + param_len > body.len() {
40 return Err(Error::InvalidDescriptor {
41 tag: TAG,
42 reason: "dvb_j_application_descriptor parameter overruns body",
43 });
44 }
45 parameters.push(&body[pos..pos + param_len]);
46 pos += param_len;
47 }
48 Ok(Self { parameters })
49 }
50}
51
52impl Serialize for DvbJApplicationDescriptor<'_> {
53 type Error = crate::error::Error;
54 fn serialized_len(&self) -> usize {
55 HEADER_LEN + self.parameters.iter().map(|p| 1 + p.len()).sum::<usize>()
56 }
57
58 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
59 for p in &self.parameters {
61 if p.len() > u8::MAX as usize {
62 return Err(Error::InvalidDescriptor {
63 tag: TAG,
64 reason: "dvb_j_application_descriptor parameter exceeds 255 bytes",
65 });
66 }
67 }
68 let body_len = self.serialized_len() - HEADER_LEN;
69 if body_len > u8::MAX as usize {
70 return Err(Error::InvalidDescriptor {
71 tag: TAG,
72 reason: "dvb_j_application_descriptor body exceeds 255 bytes",
73 });
74 }
75 let len = self.serialized_len();
76 if buf.len() < len {
77 return Err(Error::OutputBufferTooSmall {
78 need: len,
79 have: buf.len(),
80 });
81 }
82 buf[0] = TAG;
83 buf[1] = body_len as u8;
84 let mut pos = HEADER_LEN;
85 for p in &self.parameters {
86 buf[pos] = p.len() as u8;
87 pos += 1;
88 buf[pos..pos + p.len()].copy_from_slice(p);
89 pos += p.len();
90 }
91 Ok(len)
92 }
93}
94
95impl<'a> crate::traits::DescriptorDef<'a> for DvbJApplicationDescriptor<'a> {
96 const TAG: u8 = TAG;
97 const NAME: &'static str = "DVB_J_APPLICATION";
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn parse_empty() {
106 let bytes = [TAG, 0];
107 let d = DvbJApplicationDescriptor::parse(&bytes).unwrap();
108 assert!(d.parameters.is_empty());
109 }
110
111 #[test]
112 fn parse_two_params() {
113 let bytes = [
114 TAG, 6, 2, b'a', b'b', 2, b'c', b'd', ];
118 let d = DvbJApplicationDescriptor::parse(&bytes).unwrap();
119 assert_eq!(d.parameters.len(), 2);
120 assert_eq!(d.parameters[0], b"ab");
121 assert_eq!(d.parameters[1], b"cd");
122 }
123
124 #[test]
125 fn parse_truncated_param_value() {
126 let bytes = [
127 TAG, 3, 4, b'a',
129 b'b', ];
132 assert!(DvbJApplicationDescriptor::parse(&bytes).is_err());
133 }
134
135 #[test]
136 fn serialize_round_trip() {
137 let d = DvbJApplicationDescriptor {
138 parameters: vec![&b"hello"[..], &b"world"[..]],
139 };
140 let mut buf = vec![0u8; d.serialized_len()];
141 d.serialize_into(&mut buf).unwrap();
142 let re = DvbJApplicationDescriptor::parse(&buf).unwrap();
143 assert_eq!(d, re);
144 }
145
146 #[test]
147 fn serialize_byte_identical() {
148 let bytes = [
149 TAG, 4, 1, b'a', 1, b'b', ];
153 let d = DvbJApplicationDescriptor::parse(&bytes).unwrap();
154 let mut buf = vec![0u8; d.serialized_len()];
155 d.serialize_into(&mut buf).unwrap();
156 assert_eq!(buf.as_slice(), &bytes[..]);
157 }
158}