Skip to main content

dvb_si/collect/
sdt.rs

1use crate::descriptors::DescriptorRegistry;
2use crate::tables::sdt;
3
4use super::{CompleteSectionSet, ParsedDescriptorLoop};
5
6/// Service entry in a complete SDT.
7#[derive(Debug)]
8#[non_exhaustive]
9pub struct CompleteSdtService<'a> {
10    /// service_id.
11    pub service_id: u16,
12    /// EIT schedule flag.
13    pub eit_schedule_flag: bool,
14    /// EIT present/following flag.
15    pub eit_present_following_flag: bool,
16    /// 3-bit running status.
17    pub running_status: u8,
18    /// free_CA_mode.
19    pub free_ca_mode: bool,
20    /// Typed descriptor loop for this service.
21    pub descriptors: ParsedDescriptorLoop<'a>,
22}
23
24/// Complete logical Service Description Table.
25#[derive(Debug)]
26#[non_exhaustive]
27pub struct CompleteSdt<'a> {
28    /// Variant discriminator.
29    pub kind: sdt::SdtKind,
30    /// transport_stream_id of the described TS.
31    pub transport_stream_id: u16,
32    /// 5-bit version_number.
33    pub version_number: u8,
34    /// current_next_indicator bit.
35    pub current_next_indicator: bool,
36    /// original_network_id of the described TS.
37    pub original_network_id: u16,
38    /// Services from all sections in wire order.
39    pub services: Vec<CompleteSdtService<'a>>,
40}
41
42impl<'a> CompleteSdt<'a> {
43    pub(crate) fn parse(
44        set: &'a CompleteSectionSet,
45        registry: Option<&'a DescriptorRegistry>,
46    ) -> crate::Result<Self> {
47        let sections: Vec<sdt::SdtSection<'a>> = set.parse_sections()?;
48        let first = sections.first().ok_or(crate::Error::BufferTooShort {
49            need: 1,
50            have: 0,
51            what: "CompleteSdt sections",
52        })?;
53        let mut services = Vec::new();
54        for section in &sections {
55            services.extend(section.services.iter().map(|svc| CompleteSdtService {
56                service_id: svc.service_id,
57                eit_schedule_flag: svc.eit_schedule_flag,
58                eit_present_following_flag: svc.eit_present_following_flag,
59                running_status: svc.running_status,
60                free_ca_mode: svc.free_ca_mode,
61                descriptors: ParsedDescriptorLoop::parse(svc.descriptors, registry),
62            }));
63        }
64        Ok(Self {
65            kind: first.kind,
66            transport_stream_id: first.transport_stream_id,
67            version_number: first.version_number,
68            current_next_indicator: first.current_next_indicator,
69            original_network_id: first.original_network_id,
70            services,
71        })
72    }
73}