scuffle_mp4/boxes/traits.rs
1use std::io;
2
3use byteorder::WriteBytesExt;
4use bytes::Bytes;
5
6use super::header::BoxHeader;
7
8pub trait BoxType {
9 const NAME: [u8; 4];
10
11 /// Parse a box from a byte stream. The basic header is already parsed.
12 fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self>
13 where
14 Self: Sized;
15
16 /// The size of the box without the basic header.
17 fn primitive_size(&self) -> u64;
18
19 /// Write the box to a byte stream. The basic header is already written.
20 fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()>;
21
22 /// Write the box to a byte stream.
23 fn mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
24 self.validate()?;
25
26 let size = self.size();
27 if size > u32::MAX as u64 {
28 writer.write_u32::<byteorder::BigEndian>(1)?;
29 } else {
30 writer.write_u32::<byteorder::BigEndian>(size as u32)?;
31 }
32
33 writer.write_all(&Self::NAME)?;
34
35 if size > u32::MAX as u64 {
36 writer.write_u64::<byteorder::BigEndian>(size)?;
37 }
38
39 self.primitive_mux(writer)
40 }
41
42 /// Size of the box including the basic header.
43 fn size(&self) -> u64 {
44 let primitive_size = self.primitive_size() + 8;
45
46 if primitive_size > u32::MAX as u64 {
47 primitive_size + 8
48 } else {
49 primitive_size
50 }
51 }
52
53 /// Validate the box.
54 fn validate(&self) -> io::Result<()> {
55 Ok(())
56 }
57}