async_mp4/mp4box/
box_root.rs

1use async_trait::async_trait;
2use std::io::SeekFrom;
3use std::ops::{Deref, DerefMut};
4use futures::AsyncSeekExt;
5use crate::bytes_read::ReadMp4;
6use crate::bytes_write::{Mp4Writable, WriteMp4};
7use crate::error::MalformedBoxError::{ReadingWrongBox, UnknownSizeForUnknownBox};
8use crate::error::MP4Error;
9use crate::header::BoxHeader;
10use crate::mp4box::box_trait::{BoxRead, BoxWrite, IBox, PartialBox, PartialBoxRead, PartialBoxWrite};
11use crate::r#type::BoxType;
12use crate::size::BoxSize::Known;
13
14#[derive(Debug, Clone, Default, Eq, PartialEq, Hash)]
15pub struct MP4Box<P>
16    where
17        P: PartialBox<ParentData=()>
18{
19    pub inner: P,
20}
21
22impl<P> From<P> for MP4Box<P> where
23    P: PartialBox<ParentData=()>
24{
25    fn from(inner: P) -> Self {
26        Self{inner}
27    }
28}
29
30impl<P> MP4Box<P>
31    where
32        P: PartialBox<ParentData=()>
33{
34    fn header(&self) -> BoxHeader {
35        BoxHeader::from_id_and_inner_size(P::ID, self.inner.byte_size())
36    }
37}
38
39impl<P> BoxWrite for MP4Box<P>
40    where
41        P: PartialBox<ParentData=()> + PartialBoxWrite + Send + Sync,
42{
43    fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
44        let mut count = 0;
45        count += self.header().write(writer)?;
46        count += self.inner.write_data(writer)?;
47        count += self.inner.write_children(writer)?;
48        debug_assert!(count == self.byte_size(), "Byte Size is not equal to written size");
49        Ok(count)
50    }
51}
52
53impl<P> IBox for MP4Box<P>
54    where
55        P: PartialBox<ParentData=()>
56{
57    fn byte_size(&self) -> usize {
58        self.header().byte_size() + self.inner.byte_size()
59    }
60
61    const ID: BoxType = P::ID;
62}
63
64#[async_trait]
65impl<P> BoxRead for MP4Box<P>
66    where
67        P: PartialBox<ParentData=()> + PartialBoxRead + Send + Sync,
68{
69    async fn read<R: ReadMp4>(header: BoxHeader, reader: &mut R) -> Result<Self, MP4Error> {
70        let actual = header.id;
71        let  target = Self::ID;
72        if actual != target {
73            return Err(ReadingWrongBox {actual, target}.into())
74        }
75        let start = reader.seek(SeekFrom::Current(0)).await? - header.byte_size() as u64;
76        let size = header.size;
77        let mut inner = P::read_data((), reader).await?;
78        while !size.ended(start, reader).await? {
79            let header: BoxHeader = reader.read().await?;
80            let pos = reader.seek(SeekFrom::Current(0)).await?;
81            let size = header.size_minus_self();
82            inner.read_child(header, reader).await?;
83            if let Known(size) = size { // we do the check here because it's far safer
84                reader.seek(SeekFrom::Start(pos + size as u64)).await?;
85            } else {
86                return Err(UnknownSizeForUnknownBox.into());
87            }
88        }
89        Ok(Self { inner })
90    }
91}
92
93impl<P> Deref for MP4Box<P>
94    where
95        P: PartialBox<ParentData=()>
96{
97    type Target = P;
98
99    fn deref(&self) -> &Self::Target {
100        &self.inner
101    }
102}
103
104impl<P> DerefMut for MP4Box<P>
105    where
106        P: PartialBox<ParentData=()>
107{
108    fn deref_mut (&mut self) -> &mut Self::Target {
109        &mut self.inner
110    }
111}