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