Skip to main content

dvb_si/collect/
sdt.rs

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