Skip to main content

dvb_si/descriptors/
ancillary_data.rs

1//! Ancillary Data Descriptor — ETSI EN 300 468 §6.2.3 (tag 0x6B, Table 15, PDF p. 55).
2//!
3//! Carried inside the PMT ES_info loop. Fixed 1-byte body: a bit-flag field
4//! `ancillary_data_identifier` whose bits select which ancillary-data formats
5//! are present (Table 16: DVD video AD, extended AD, announcement switching,
6//! DAB AD, ScF-CRC, MPEG-4 AD, RDS-via-UECP). We carry the raw flag byte; the
7//! bit meanings are defined by ETSI TS 101 154 and not interpreted here.
8
9use super::descriptor_body;
10use crate::error::{Error, Result};
11use dvb_common::{Parse, Serialize};
12
13/// Descriptor tag for ancillary_data_descriptor.
14pub const TAG: u8 = 0x6B;
15/// Length of the header (tag byte + length byte).
16pub const HEADER_LEN: usize = 2;
17/// Fixed body length: one identifier flag byte.
18pub const BODY_LEN: usize = 1;
19
20/// Ancillary Data Descriptor.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize))]
23pub struct AncillaryDataDescriptor {
24    /// 8-bit ancillary_data_identifier flag field (Table 16).
25    pub ancillary_data_identifier: u8,
26}
27
28impl<'a> Parse<'a> for AncillaryDataDescriptor {
29    type Error = crate::error::Error;
30    fn parse(bytes: &'a [u8]) -> Result<Self> {
31        let body = descriptor_body(
32            bytes,
33            TAG,
34            "AncillaryDataDescriptor",
35            "unexpected tag for ancillary_data_descriptor",
36        )?;
37        if body.len() != BODY_LEN {
38            return Err(Error::InvalidDescriptor {
39                tag: TAG,
40                reason: "ancillary_data_descriptor length must be exactly 1",
41            });
42        }
43        Ok(Self {
44            ancillary_data_identifier: body[0],
45        })
46    }
47}
48
49impl Serialize for AncillaryDataDescriptor {
50    type Error = crate::error::Error;
51    fn serialized_len(&self) -> usize {
52        HEADER_LEN + BODY_LEN
53    }
54
55    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
56        let len = self.serialized_len();
57        if buf.len() < len {
58            return Err(Error::OutputBufferTooSmall {
59                need: len,
60                have: buf.len(),
61            });
62        }
63        buf[0] = TAG;
64        buf[1] = BODY_LEN as u8;
65        buf[HEADER_LEN] = self.ancillary_data_identifier;
66        Ok(len)
67    }
68}
69impl<'a> crate::traits::DescriptorDef<'a> for AncillaryDataDescriptor {
70    const TAG: u8 = TAG;
71    const NAME: &'static str = "ANCILLARY_DATA";
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn parse_extracts_identifier() {
80        let bytes = [TAG, 1, 0x55];
81        let d = AncillaryDataDescriptor::parse(&bytes).unwrap();
82        assert_eq!(d.ancillary_data_identifier, 0x55);
83    }
84
85    #[test]
86    fn parse_rejects_wrong_tag() {
87        assert!(matches!(
88            AncillaryDataDescriptor::parse(&[0x6C, 1, 0]).unwrap_err(),
89            Error::InvalidDescriptor { tag: 0x6C, .. }
90        ));
91    }
92
93    #[test]
94    fn parse_rejects_wrong_length() {
95        assert!(matches!(
96            AncillaryDataDescriptor::parse(&[TAG, 2, 0, 0]).unwrap_err(),
97            Error::InvalidDescriptor { tag: TAG, .. }
98        ));
99    }
100
101    #[test]
102    fn parse_rejects_short_body() {
103        assert!(matches!(
104            AncillaryDataDescriptor::parse(&[TAG, 1]).unwrap_err(),
105            Error::BufferTooShort { .. }
106        ));
107    }
108
109    #[test]
110    fn serialize_round_trip() {
111        let d = AncillaryDataDescriptor {
112            ancillary_data_identifier: 0xA3,
113        };
114        let mut buf = vec![0u8; d.serialized_len()];
115        d.serialize_into(&mut buf).unwrap();
116        assert_eq!(buf, [TAG, 1, 0xA3]);
117        assert_eq!(AncillaryDataDescriptor::parse(&buf).unwrap(), d);
118    }
119
120    #[test]
121    fn serialize_rejects_too_small_buffer() {
122        let d = AncillaryDataDescriptor {
123            ancillary_data_identifier: 0,
124        };
125        let mut buf = vec![0u8; 2];
126        assert!(matches!(
127            d.serialize_into(&mut buf).unwrap_err(),
128            Error::OutputBufferTooSmall { .. }
129        ));
130    }
131
132    #[cfg(feature = "serde")]
133    #[test]
134    fn serde_round_trip() {
135        let d = AncillaryDataDescriptor {
136            ancillary_data_identifier: 0xA3,
137        };
138        let json = serde_json::to_string(&d).unwrap();
139        // Serialize-only: assert the emitted JSON re-parses (serialize-stable).
140        let _v: serde_json::Value = serde_json::from_str(&json).unwrap();
141    }
142}