dvb_subtitle/segments/
end_of_display_set.rs1use crate::error::{Error, Result};
4use broadcast_common::len::{need_in, need_out};
5use broadcast_common::{Parse, Serialize};
6
7pub const SEGMENT_TYPE: u8 = 0x80;
9pub const HEADER_LEN: usize = 6;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize))]
15pub struct EndOfDisplaySetSegment {
16 pub page_id: u16,
18}
19
20impl<'a> Parse<'a> for EndOfDisplaySetSegment {
21 type Error = Error;
22
23 fn parse(bytes: &'a [u8]) -> Result<Self> {
24 need_in(bytes, HEADER_LEN, "end_of_display_set_segment")?;
25 if bytes[0] != crate::pes_data_field::SYNC_BYTE {
26 return Err(Error::InvalidSync(broadcast_common::error::InvalidSync {
27 what: "sync_byte",
28 expected: u32::from(crate::pes_data_field::SYNC_BYTE),
29 found: u32::from(bytes[0]),
30 }));
31 }
32 if bytes[1] != SEGMENT_TYPE {
33 return Err(Error::UnknownSegmentType(bytes[1]));
34 }
35 let page_id = u16::from_be_bytes([bytes[2], bytes[3]]);
36 let segment_length = u16::from_be_bytes([bytes[4], bytes[5]]);
37 if segment_length != 0 {
38 return Err(Error::SegmentTooLarge);
39 }
40 Ok(EndOfDisplaySetSegment { page_id })
41 }
42}
43
44impl Serialize for EndOfDisplaySetSegment {
45 type Error = Error;
46
47 fn serialized_len(&self) -> usize {
48 HEADER_LEN
49 }
50
51 fn serialize_into(&self, buf: &mut [u8]) -> core::result::Result<usize, Self::Error> {
52 let len = self.serialized_len();
53 need_out(buf, len)?;
54 buf[0] = 0x0F;
55 buf[1] = SEGMENT_TYPE;
56 buf[2..4].copy_from_slice(&self.page_id.to_be_bytes());
57 buf[4..6].copy_from_slice(&0u16.to_be_bytes()); Ok(len)
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use broadcast_common::{Parse, Serialize};
66
67 #[test]
68 fn serialize_into_short_output_is_output_buffer_too_small() {
69 let bytes = [0x0F, 0x80, 0x00, 0x01, 0x00, 0x00];
70 let seg = EndOfDisplaySetSegment::parse(&bytes).unwrap();
71 let mut out = [0u8; 5];
72 assert_eq!(
73 seg.serialize_into(&mut out),
74 Err(crate::Error::OutputBufferTooSmall(
75 broadcast_common::error::OutputBufferTooSmall { need: 6, have: 5 }
76 ))
77 );
78 }
79
80 #[test]
81 fn round_trip() {
82 let bytes = [0x0F, 0x80, 0x00, 0x01, 0x00, 0x00];
83 let seg = EndOfDisplaySetSegment::parse(&bytes).unwrap();
84 assert_eq!(seg.page_id, 1);
85 let out = seg.try_to_bytes().unwrap();
86 assert_eq!(out, bytes);
87
88 let mut seg2 = seg.clone();
90 seg2.page_id = 5;
91 let out2 = seg2.try_to_bytes().unwrap();
92 assert_ne!(out2, bytes);
93 let reparse = EndOfDisplaySetSegment::parse(&out2).unwrap();
94 assert_eq!(reparse.page_id, 5);
95 }
96
97 #[test]
103 fn rejects_bad_sync_byte() {
104 let bytes = [0x00, 0x80, 0x00, 0x01, 0x00, 0x00];
105 assert!(matches!(
106 EndOfDisplaySetSegment::parse(&bytes),
107 Err(Error::InvalidSync(broadcast_common::error::InvalidSync {
108 found: 0x00,
109 ..
110 }))
111 ));
112 }
113}