Skip to main content

dvb_si/descriptors/
private_data_indicator.rs

1//! Private Data Indicator Descriptor — ISO/IEC 13818-1 §2.6.22 (tag 0x0F).
2//!
3//! Carries a 4-byte private data specifier that identifies the organization
4//! or entity that defined the private data carried in the associated stream.
5
6use super::descriptor_body;
7pub use super::private_data_specifier::private_data_specifier_name;
8use crate::error::{Error, Result};
9use dvb_common::{Parse, Serialize};
10
11/// Descriptor tag for private_data_indicator_descriptor.
12pub const TAG: u8 = 0x0F;
13const HEADER_LEN: usize = 2;
14const BODY_LEN: u8 = 4;
15
16/// Private Data Indicator Descriptor.
17///
18/// The `private_data_specifier` is a 32-bit value assigned by a standards body
19/// or industry consortium to identify the organization that defined the private
20/// data format used in the associated elementary stream.
21#[derive(Debug, Clone, PartialEq, Eq)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize))]
23pub struct PrivateDataIndicatorDescriptor {
24    /// 32-bit registered private_data_specifier (ETSI Table 85, PDF p. 98).
25    pub private_data_specifier: u32,
26}
27
28impl<'a> Parse<'a> for PrivateDataIndicatorDescriptor {
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            "PrivateDataIndicatorDescriptor",
36            "unexpected tag for private_data_indicator_descriptor",
37        )?;
38        if body.len() != BODY_LEN as usize {
39            return Err(Error::InvalidDescriptor {
40                tag: TAG,
41                reason: "private_data_indicator_descriptor length must equal 4",
42            });
43        }
44        let (hdr, _) = body
45            .split_first_chunk::<4>()
46            .ok_or(Error::InvalidDescriptor {
47                tag: TAG,
48                reason: "private_data_indicator_descriptor length must equal 4",
49            })?;
50        let private_data_specifier = u32::from_be_bytes(*hdr);
51        Ok(Self {
52            private_data_specifier,
53        })
54    }
55}
56
57impl Serialize for PrivateDataIndicatorDescriptor {
58    type Error = crate::error::Error;
59
60    fn serialized_len(&self) -> usize {
61        HEADER_LEN + BODY_LEN as usize
62    }
63
64    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
65        let len = self.serialized_len();
66        if buf.len() < len {
67            return Err(Error::OutputBufferTooSmall {
68                need: len,
69                have: buf.len(),
70            });
71        }
72        buf[0] = TAG;
73        buf[1] = BODY_LEN;
74        buf[HEADER_LEN..HEADER_LEN + 4].copy_from_slice(&self.private_data_specifier.to_be_bytes());
75        Ok(len)
76    }
77}
78impl<'a> crate::traits::DescriptorDef<'a> for PrivateDataIndicatorDescriptor {
79    const TAG: u8 = TAG;
80    const NAME: &'static str = "PRIVATE_DATA_INDICATOR";
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn parse_private_data_specifier() {
89        let bytes = [TAG, 4, 0x00, 0x00, 0x00, 0x01];
90        let d = PrivateDataIndicatorDescriptor::parse(&bytes).unwrap();
91        assert_eq!(d.private_data_specifier, 0x0000_0001);
92    }
93
94    #[test]
95    fn parse_rejects_wrong_tag() {
96        let err = PrivateDataIndicatorDescriptor::parse(&[0x10, 4, 0, 0, 0, 0]).unwrap_err();
97        assert!(matches!(err, Error::InvalidDescriptor { tag: 0x10, .. }));
98    }
99
100    #[test]
101    fn parse_rejects_wrong_length() {
102        let bytes = [TAG, 3, 0, 0, 0, 0];
103        let err = PrivateDataIndicatorDescriptor::parse(&bytes).unwrap_err();
104        assert!(matches!(err, Error::InvalidDescriptor { .. }));
105    }
106
107    #[test]
108    fn parse_rejects_short_buffer() {
109        let err = PrivateDataIndicatorDescriptor::parse(&[TAG]).unwrap_err();
110        assert!(matches!(err, Error::BufferTooShort { .. }));
111    }
112
113    #[test]
114    fn serialize_round_trip() {
115        let d = PrivateDataIndicatorDescriptor {
116            private_data_specifier: 0xAABB_CCDD,
117        };
118        let mut buf = vec![0u8; d.serialized_len()];
119        d.serialize_into(&mut buf).unwrap();
120        let reparsed = PrivateDataIndicatorDescriptor::parse(&buf).unwrap();
121        assert_eq!(d, reparsed);
122    }
123
124    #[test]
125    fn descriptor_length_matches_payload() {
126        let d = PrivateDataIndicatorDescriptor {
127            private_data_specifier: 0x0000_0001,
128        };
129        assert_eq!(d.serialized_len() - 2, 4);
130    }
131}