Skip to main content

dvb_si/descriptors/
default_authority.rs

1//! Default Authority Descriptor — ETSI TS 102 323 §12.2.1 (tag 0x73).
2//!
3//! Carried inside NIT, BAT, SDT, EIT to provide the default TV-Anytime
4//! authority prefix used when resolving relative CRIDs.
5
6use crate::error::{Error, Result};
7use crate::traits::Descriptor;
8use dvb_common::{Parse, Serialize};
9
10/// Descriptor tag for default_authority_descriptor.
11pub const TAG: u8 = 0x73;
12const HEADER_LEN: usize = 2;
13
14/// Default Authority Descriptor.
15#[derive(Debug, Clone, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize))]
17#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
18pub struct DefaultAuthorityDescriptor<'a> {
19    /// Raw ASCII default authority bytes (e.g. b"bbc.co.uk").
20    pub default_authority: &'a [u8],
21}
22
23impl<'a> Parse<'a> for DefaultAuthorityDescriptor<'a> {
24    type Error = crate::error::Error;
25    fn parse(bytes: &'a [u8]) -> Result<Self> {
26        if bytes.len() < HEADER_LEN {
27            return Err(Error::BufferTooShort {
28                need: HEADER_LEN,
29                have: bytes.len(),
30                what: "DefaultAuthorityDescriptor header",
31            });
32        }
33        if bytes[0] != TAG {
34            return Err(Error::InvalidDescriptor {
35                tag: bytes[0],
36                reason: "unexpected tag for default authority descriptor",
37            });
38        }
39        let length = bytes[1] as usize;
40        let end = HEADER_LEN + length;
41        if bytes.len() < end {
42            return Err(Error::BufferTooShort {
43                need: end,
44                have: bytes.len(),
45                what: "DefaultAuthorityDescriptor body",
46            });
47        }
48        Ok(Self {
49            default_authority: &bytes[HEADER_LEN..end],
50        })
51    }
52}
53
54impl Serialize for DefaultAuthorityDescriptor<'_> {
55    type Error = crate::error::Error;
56    fn serialized_len(&self) -> usize {
57        HEADER_LEN + self.default_authority.len()
58    }
59
60    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
61        let len = self.serialized_len();
62        if buf.len() < len {
63            return Err(Error::OutputBufferTooSmall {
64                need: len,
65                have: buf.len(),
66            });
67        }
68        buf[0] = TAG;
69        buf[1] = self.descriptor_length();
70        buf[HEADER_LEN..len].copy_from_slice(self.default_authority);
71        Ok(len)
72    }
73}
74
75impl<'a> Descriptor<'a> for DefaultAuthorityDescriptor<'a> {
76    const TAG: u8 = TAG;
77    fn descriptor_length(&self) -> u8 {
78        self.default_authority.len() as u8
79    }
80}
81
82impl<'a> crate::traits::DescriptorDef<'a> for DefaultAuthorityDescriptor<'a> {
83    const TAG: u8 = TAG;
84    const NAME: &'static str = "DEFAULT_AUTHORITY";
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    #[test]
92    fn parse_extracts_authority_bytes() {
93        let bytes = [TAG, 9, b'b', b'b', b'c', b'.', b'c', b'o', b'.', b'u', b'k'];
94        let d = DefaultAuthorityDescriptor::parse(&bytes).unwrap();
95        assert_eq!(d.default_authority, b"bbc.co.uk");
96    }
97
98    #[test]
99    fn parse_rejects_wrong_tag() {
100        assert!(matches!(
101            DefaultAuthorityDescriptor::parse(&[0x7A, 1, 0]).unwrap_err(),
102            Error::InvalidDescriptor { tag: 0x7A, .. }
103        ));
104    }
105
106    #[test]
107    fn parse_rejects_short_header() {
108        assert!(matches!(
109            DefaultAuthorityDescriptor::parse(&[TAG]).unwrap_err(),
110            Error::BufferTooShort { .. }
111        ));
112    }
113
114    #[test]
115    fn parse_rejects_length_overrunning_buffer() {
116        let bytes = [TAG, 5, 1, 2, 3];
117        assert!(matches!(
118            DefaultAuthorityDescriptor::parse(&bytes).unwrap_err(),
119            Error::BufferTooShort { .. }
120        ));
121    }
122
123    #[test]
124    fn empty_authority_is_valid() {
125        let bytes = [TAG, 0];
126        let d = DefaultAuthorityDescriptor::parse(&bytes).unwrap();
127        assert!(d.default_authority.is_empty());
128    }
129
130    #[test]
131    fn serialize_round_trip() {
132        let d = DefaultAuthorityDescriptor {
133            default_authority: b"example.com",
134        };
135        let mut buf = vec![0u8; d.serialized_len()];
136        d.serialize_into(&mut buf).unwrap();
137        assert_eq!(DefaultAuthorityDescriptor::parse(&buf).unwrap(), d);
138    }
139
140    #[test]
141    fn serialize_rejects_too_small_buffer() {
142        let d = DefaultAuthorityDescriptor {
143            default_authority: b"test",
144        };
145        let mut buf = vec![0u8; 1];
146        assert!(matches!(
147            d.serialize_into(&mut buf).unwrap_err(),
148            Error::OutputBufferTooSmall { .. }
149        ));
150    }
151}