libmpegts 0.3.2

MPEG-TS Library
Documentation
use super::PsiSectionError;

/// Reference to a single MPEG-TS descriptor (tag + length + data).
#[derive(Debug, Clone, Copy)]
pub struct DescriptorRef<'a>(&'a [u8]);

impl<'a> DescriptorRef<'a> {
    pub fn tag(&self) -> u8 {
        self.0[0]
    }

    pub fn data(&self) -> &'a [u8] {
        &self.0[2 ..]
    }

    pub fn bytes(&self) -> &'a [u8] {
        self.0
    }
}

/// Reference to a list of MPEG-TS descriptors.
pub struct DescriptorsRef<'a>(&'a [u8]);

impl<'a> From<&'a [u8]> for DescriptorsRef<'a> {
    fn from(value: &'a [u8]) -> Self {
        DescriptorsRef(value)
    }
}

impl<'a> IntoIterator for DescriptorsRef<'a> {
    type Item = Result<DescriptorRef<'a>, PsiSectionError>;
    type IntoIter = DescriptorIter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        DescriptorIter {
            data: self.0,
            offset: 0,
        }
    }
}

/// Iterator over MPEG-TS descriptors.
pub struct DescriptorIter<'a> {
    data: &'a [u8],
    offset: usize,
}

impl<'a> Iterator for DescriptorIter<'a> {
    type Item = Result<DescriptorRef<'a>, PsiSectionError>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.offset >= self.data.len() {
            return None;
        }
        if self.offset + 2 > self.data.len() {
            return Some(Err(PsiSectionError::InvalidDescriptorLength));
        }
        let end = self.offset + 2 + self.data[self.offset + 1] as usize;
        if end > self.data.len() {
            return Some(Err(PsiSectionError::InvalidDescriptorLength));
        }
        let desc = DescriptorRef(&self.data[self.offset .. end]);
        self.offset = end;
        Some(Ok(desc))
    }
}