flowly_mp4/mp4box/
data.rs

1use serde::Serialize;
2use std::convert::TryFrom;
3
4use crate::mp4box::*;
5
6#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
7pub struct DataBox {
8    pub data: Vec<u8>,
9    pub data_type: DataType,
10}
11
12impl DataBox {
13    pub fn get_type(&self) -> BoxType {
14        BoxType::DataBox
15    }
16
17    pub fn get_size(&self) -> u64 {
18        let mut size = HEADER_SIZE;
19        size += 4; // data_type
20        size += 4; // reserved
21        size += self.data.len() as u64;
22        size
23    }
24}
25
26impl Mp4Box for DataBox {
27    const TYPE: BoxType = BoxType::DataBox;
28
29    fn box_size(&self) -> u64 {
30        self.get_size()
31    }
32
33    fn to_json(&self) -> Result<String, Error> {
34        Ok(serde_json::to_string(&self).unwrap())
35    }
36
37    fn summary(&self) -> Result<String, Error> {
38        let s = format!("type={:?} len={}", self.data_type, self.data.len());
39        Ok(s)
40    }
41}
42
43impl BlockReader for DataBox {
44    fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
45        let data_type = DataType::try_from(reader.get_u32())?;
46        reader.get_u32(); // reserved = 0
47
48        Ok(DataBox {
49            data: reader.collect(reader.remaining())?,
50            data_type,
51        })
52    }
53
54    fn size_hint() -> usize {
55        8
56    }
57}
58
59impl<W: Write> WriteBox<&mut W> for DataBox {
60    fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
61        let size = self.box_size();
62        BoxHeader::new(Self::TYPE, size).write(writer)?;
63
64        writer.write_u32::<BigEndian>(self.data_type.clone() as u32)?;
65        writer.write_u32::<BigEndian>(0)?; // reserved = 0
66        writer.write_all(&self.data)?;
67
68        Ok(size)
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75    use crate::mp4box::BoxHeader;
76
77    #[tokio::test]
78    async fn test_data() {
79        let src_box = DataBox {
80            data_type: DataType::Text,
81            data: b"test_data".to_vec(),
82        };
83        let mut buf = Vec::new();
84        src_box.write_box(&mut buf).unwrap();
85        assert_eq!(buf.len(), src_box.box_size() as usize);
86
87        let mut reader = buf.as_slice();
88        let header = BoxHeader::read(&mut reader, &mut 0).await.unwrap().unwrap();
89        assert_eq!(header.kind, BoxType::DataBox);
90        assert_eq!(src_box.box_size(), header.size);
91
92        let dst_box = DataBox::read_block(&mut reader).unwrap();
93        assert_eq!(src_box, dst_box);
94    }
95
96    #[tokio::test]
97    async fn test_data_empty() {
98        let src_box = DataBox::default();
99        let mut buf = Vec::new();
100        src_box.write_box(&mut buf).unwrap();
101        assert_eq!(buf.len(), src_box.box_size() as usize);
102
103        let mut reader = buf.as_slice();
104        let header = BoxHeader::read(&mut reader, &mut 0).await.unwrap().unwrap();
105        assert_eq!(header.kind, BoxType::DataBox);
106        assert_eq!(src_box.box_size(), header.size);
107
108        let dst_box = DataBox::read_block(&mut reader).unwrap();
109        assert_eq!(src_box, dst_box);
110    }
111}