1use crate::any::AnySegment;
7use crate::error::{Error, Result};
8use dvb_common::{Parse, Serialize};
9
10pub const DATA_IDENTIFIER: u8 = 0x20;
12pub const SUBTITLE_STREAM_ID: u8 = 0x00;
14pub const SYNC_BYTE: u8 = 0x0F;
16pub const END_OF_PES_MARKER: u8 = 0xFF;
18
19const MIN_FIELD_LEN: usize = 3;
21const SEGMENT_HEADER_LEN: usize = 6;
23
24#[derive(Debug, Clone, PartialEq, Eq)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize))]
30pub struct PesDataField<'a> {
31 pub subtitle_stream_id: u8,
33 #[cfg_attr(feature = "serde", serde(borrow))]
35 pub segments: alloc::vec::Vec<AnySegment<'a>>,
36 #[cfg_attr(feature = "serde", serde(skip))]
39 pub(crate) suffix: &'a [u8],
40}
41
42impl<'a> Parse<'a> for PesDataField<'a> {
43 type Error = Error;
44
45 fn parse(bytes: &'a [u8]) -> Result<Self> {
46 if bytes.len() < MIN_FIELD_LEN {
47 return Err(Error::BufferTooShort {
48 need: MIN_FIELD_LEN,
49 have: bytes.len(),
50 what: "PES_data_field",
51 });
52 }
53 if bytes[0] != DATA_IDENTIFIER {
54 return Err(Error::BadDataIdentifier(bytes[0]));
55 }
56 let subtitle_stream_id = bytes[1];
57 if subtitle_stream_id != SUBTITLE_STREAM_ID {
58 }
60
61 let mut pos: usize = 2;
62 let mut segments = alloc::vec::Vec::new();
63
64 while pos < bytes.len() && bytes[pos] == SYNC_BYTE {
66 if pos + SEGMENT_HEADER_LEN > bytes.len() {
67 break;
69 }
70 let segment_length = u16::from_be_bytes([bytes[pos + 4], bytes[pos + 5]]) as usize;
71 let segment_end = pos + SEGMENT_HEADER_LEN + segment_length;
72 if segment_end > bytes.len() {
73 break;
76 }
77
78 let seg_bytes = &bytes[pos..segment_end];
79 let segment_type = bytes[pos + 1];
80
81 match AnySegment::dispatch(segment_type, seg_bytes) {
82 Some(Ok(seg)) => segments.push(seg),
83 Some(Err(_e)) => {
84 segments.push(AnySegment::Unknown {
86 segment_type,
87 page_id: u16::from_be_bytes([seg_bytes[2], seg_bytes[3]]),
88 data: &seg_bytes[SEGMENT_HEADER_LEN..],
89 });
90 }
91 None => {
92 segments.push(AnySegment::Unknown {
94 segment_type,
95 page_id: u16::from_be_bytes([seg_bytes[2], seg_bytes[3]]),
96 data: &seg_bytes[SEGMENT_HEADER_LEN..],
97 });
98 }
99 }
100
101 pos = segment_end;
102 }
103
104 let suffix = &bytes[pos..];
106
107 Ok(PesDataField {
108 subtitle_stream_id,
109 segments,
110 suffix,
111 })
112 }
113}
114
115impl Serialize for PesDataField<'_> {
116 type Error = Error;
117
118 fn serialized_len(&self) -> usize {
119 2 + self.suffix.len()
120 + self
121 .segments
122 .iter()
123 .map(|s| s.serialized_len())
124 .sum::<usize>()
125 }
126
127 fn serialize_into(&self, buf: &mut [u8]) -> core::result::Result<usize, Self::Error> {
128 let len = self.serialized_len();
129 if buf.len() < len {
130 return Err(Error::BufferTooShort {
131 need: len,
132 have: buf.len(),
133 what: "PES_data_field serialize",
134 });
135 }
136 buf[0] = DATA_IDENTIFIER;
137 buf[1] = self.subtitle_stream_id;
138 let mut off = 2;
139 for seg in &self.segments {
140 let seg_len = seg.serialized_len();
141 seg.serialize_into(&mut buf[off..off + seg_len])?;
142 off += seg_len;
143 }
144 buf[off..off + self.suffix.len()].copy_from_slice(self.suffix);
145 Ok(len)
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152 use dvb_common::Serialize;
153
154 #[test]
155 fn round_trip_single_end_of_display_set() {
156 let bytes = [
157 0x20, 0x00, 0x0F, 0x80, 0x00, 0x01, 0x00, 0x00, 0xFF, ];
161 let field = PesDataField::parse(&bytes).unwrap();
162 assert_eq!(field.segments.len(), 1);
163 let out = field.to_bytes();
164 assert_eq!(out, bytes);
165 }
166
167 #[test]
168 fn round_trip_multiple_segments() {
169 let bytes = [
170 0x20, 0x00, 0x0F, 0x14, 0x00, 0x01, 0x00, 0x05, 0x30, 0x02, 0xCF, 0x01, 0x1F,
172 0x0F, 0x10, 0x00, 0x01, 0x00, 0x08, 0x0A, 0x08, 0x01, 0x00, 0x00, 0x64, 0x00, 0x32,
174 0x0F, 0x80, 0x00, 0x01, 0x00, 0x00, 0xFF,
176 ];
177 let field = PesDataField::parse(&bytes).unwrap();
178 assert_eq!(field.segments.len(), 3);
179 assert_eq!(field.segments[0].name(), "DISPLAY_DEFINITION");
180 assert_eq!(field.segments[1].name(), "PAGE_COMPOSITION");
181 assert_eq!(field.segments[2].name(), "END_OF_DISPLAY_SET");
182 let out = field.to_bytes();
183 assert_eq!(out, bytes);
184 }
185
186 #[test]
187 fn unknown_segment_preserved() {
188 let bytes = [
189 0x20, 0x00, 0x0F, 0xA0, 0x00, 0x01, 0x00, 0x02, 0xCA, 0xFE, 0xFF,
191 ];
192 let field = PesDataField::parse(&bytes).unwrap();
193 assert_eq!(field.segments.len(), 1);
194 assert_eq!(field.segments[0].name(), "UNKNOWN");
195 let out = field.to_bytes();
196 assert_eq!(out, bytes);
197 }
198
199 #[test]
200 fn bad_data_identifier() {
201 let bytes = [0x00, 0x00, 0xFF];
202 let err = PesDataField::parse(&bytes).unwrap_err();
203 assert!(matches!(err, Error::BadDataIdentifier(0x00)));
204 }
205
206 #[test]
207 fn no_end_marker_is_ok() {
208 let bytes = [0x20, 0x00, 0x00];
210 let field = PesDataField::parse(&bytes).unwrap();
211 assert_eq!(field.segments.len(), 0);
212 }
213}