va_ts/section/
eit.rs

1use std::fmt;
2use std::time::Duration;
3
4use chrono::prelude::*;
5
6use crate::annex_c;
7use crate::descriptor::Descriptor;
8use crate::duration_fmt::DurationFmt;
9use crate::error::{Error, Kind as ErrorKind};
10use crate::result::Result;
11use crate::subtable_id::{SubtableID, SubtableIDer};
12
13use super::traits::*;
14
15/// ETSI EN 300 468 V1.15.1
16///
17/// Event Information Table
18pub struct EIT<'buf> {
19    buf: &'buf [u8],
20}
21
22impl<'buf> EIT<'buf> {
23    const HEADER_SPECIFIC_SZ: usize = 6;
24    const HEADER_FULL_SZ: usize = HEADER_SZ + SYNTAX_SECTION_SZ + Self::HEADER_SPECIFIC_SZ;
25
26    #[inline(always)]
27    pub fn new(buf: &'buf [u8]) -> EIT<'buf> {
28        EIT { buf }
29    }
30
31    #[inline(always)]
32    pub fn try_new(buf: &'buf [u8]) -> Result<EIT<'buf>> {
33        let s = Self::new(buf);
34        s.validate()?;
35        Ok(s)
36    }
37
38    #[inline(always)]
39    pub fn validate(&self) -> Result<()> {
40        Ok(())
41    }
42
43    /// seek
44    #[inline(always)]
45    fn buf_events(&self) -> &'buf [u8] {
46        let lft = Self::HEADER_FULL_SZ;
47        let mut rght = HEADER_SZ + (self.section_length() as usize);
48
49        if rght >= self.buf.len() {
50            rght = self.buf.len();
51        }
52
53        rght -= CRC32_SZ;
54
55        &self.buf[lft..rght]
56    }
57
58    #[inline(always)]
59    pub fn events(&self) -> Cursor<'buf, Event> {
60        Cursor::new(self.buf_events())
61    }
62
63    #[inline(always)]
64    pub fn service_id(&self) -> u16 {
65        self.table_id_extension()
66    }
67}
68
69trait WithEITHeaderSpecific<'buf>: Bufer<'buf> {
70    /// buffer seeked
71    #[inline(always)]
72    fn b(&self) -> &'buf [u8] {
73        &self.buf()[HEADER_SZ + SYNTAX_SECTION_SZ..]
74    }
75
76    #[inline(always)]
77    fn transport_stream_id(&self) -> u16 {
78        u16::from(self.b()[0]) | u16::from(self.b()[1])
79    }
80
81    #[inline(always)]
82    fn original_network_id(&self) -> u16 {
83        u16::from(self.b()[2]) | u16::from(self.b()[3])
84    }
85
86    #[inline(always)]
87    fn segment_last_section_number(&self) -> u8 {
88        self.b()[4]
89    }
90
91    #[inline(always)]
92    fn last_table_id(&self) -> u8 {
93        self.b()[5]
94    }
95}
96
97impl<'buf> Bufer<'buf> for EIT<'buf> {
98    fn buf(&self) -> &'buf [u8] {
99        self.buf
100    }
101}
102
103impl<'buf> WithHeader<'buf> for EIT<'buf> {}
104impl<'buf> WithTableIDExtension<'buf> for EIT<'buf> {}
105impl<'buf> WithSyntaxSection<'buf> for EIT<'buf> {}
106impl<'buf> WithEITHeaderSpecific<'buf> for EIT<'buf> {}
107impl<'buf> WithCRC32<'buf> for EIT<'buf> {}
108
109impl<'buf> fmt::Debug for EIT<'buf> {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        write!(
112            f,
113            ":EIT (:id {:?} :section-length {:3} :section {}/{})",
114            self.subtable_id(),
115            self.section_length(),
116            self.section_number(),
117            self.last_section_number(),
118        )?;
119
120        write!(f, "\n  :events")?;
121        for rese in self.events() {
122            write!(f, "\n    ")?;
123            match rese {
124                Ok(e) => {
125                    e.fmt(f)?;
126                }
127                Err(err) => {
128                    write!(f, "error parse EIT event: {}", err)?;
129                }
130            }
131        }
132
133        Ok(())
134    }
135}
136
137impl<'buf> SubtableIDer for EIT<'buf> {
138    #[inline(always)]
139    fn subtable_id(&self) -> SubtableID {
140        SubtableID::EIT(
141            self.table_id(),
142            self.service_id(),
143            self.transport_stream_id(),
144            self.original_network_id(),
145            self.version_number(),
146        )
147    }
148}
149
150pub struct Event<'buf> {
151    buf: &'buf [u8],
152}
153
154impl<'buf> Event<'buf> {
155    const HEADER_SZ: usize = 12;
156
157    #[inline(always)]
158    pub fn new(buf: &'buf [u8]) -> Event<'buf> {
159        Event { buf }
160    }
161
162    #[inline(always)]
163    pub fn validate(&self) -> Result<()> {
164        if self.buf.len() < Self::HEADER_SZ {
165            Err(Error::new(ErrorKind::Buf(self.buf.len(), Self::HEADER_SZ)))
166        } else if self.buf.len() < self.sz() {
167            Err(Error::new(ErrorKind::Buf(self.buf.len(), self.sz())))
168        } else {
169            Ok(())
170        }
171    }
172
173    #[inline(always)]
174    pub fn event_id(&self) -> u16 {
175        (u16::from(self.buf[0]) << 8) | u16::from(self.buf[1])
176    }
177
178    #[inline(always)]
179    pub fn start_time(&self) -> DateTime<Utc> {
180        // must
181        annex_c::from_bytes_into_date_time_utc(&self.buf[2..7]).unwrap()
182    }
183
184    #[inline(always)]
185    pub fn duration(&self) -> Duration {
186        // must
187        annex_c::from_bytes_into_duration(&self.buf[7..10]).unwrap()
188    }
189
190    /// seek
191    #[inline(always)]
192    fn buf_descriptors(&self) -> &'buf [u8] {
193        let lft = Self::HEADER_SZ;
194        let mut rght = lft + (self.descriptors_loop_length() as usize);
195
196        if rght >= self.buf.len() {
197            rght = self.buf.len();
198        }
199
200        &self.buf[lft..rght]
201    }
202
203    #[inline(always)]
204    pub fn descriptors(&self) -> Option<Cursor<'buf, Descriptor>> {
205        if self.descriptors_loop_length() != 0 {
206            Some(Cursor::new(self.buf_descriptors()))
207        } else {
208            None
209        }
210    }
211
212    #[inline(always)]
213    pub fn descriptors_loop_length(&self) -> u16 {
214        (u16::from(self.buf[10] & 0b0000_1111) << 8) | u16::from(self.buf[11])
215    }
216}
217
218impl<'buf> Szer for Event<'buf> {
219    #[inline(always)]
220    fn sz(&self) -> usize {
221        Self::HEADER_SZ + (self.descriptors_loop_length() as usize)
222    }
223}
224
225impl<'buf> TryNewer<'buf> for Event<'buf> {
226    #[inline(always)]
227    fn try_new(buf: &'buf [u8]) -> Result<Event<'buf>> {
228        let s = Event::new(buf);
229        s.validate()?;
230        Ok(s)
231    }
232}
233
234impl<'buf> fmt::Debug for Event<'buf> {
235    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236        write!(
237            f,
238            ":event (:start-time {} :duration {})",
239            self.start_time(),
240            DurationFmt::from(self.duration()),
241        )?;
242
243        write!(f, "\n      :descriptors")?;
244        match self.descriptors() {
245            Some(descs) => {
246                for resd in descs {
247                    write!(f, "\n        ")?;
248                    match resd {
249                        Ok(d) => {
250                            d.fmt(f)?;
251                        }
252                        Err(err) => {
253                            write!(f, "error parse descriptor: {}", err)?;
254                        }
255                    }
256                }
257            }
258            None => write!(f, " ~")?,
259        }
260
261        Ok(())
262    }
263}