1use std::io::Write;
2use std::ops::BitOr;
3use byteorder::{BigEndian, WriteBytesExt};
4use crate::error::MP4Error;
5
6pub trait FlagTrait: Copy + Default + BitOr<Output=Self> + Into<u32> + From<u32> + Send + Sync + 'static {}
7impl<T: Copy + Default + BitOr<Output=Self> + Into<u32> + From<u32> + Send + Sync + 'static> FlagTrait for T {}
8
9pub trait Mp4Writable {
10 fn byte_size(&self) -> usize;
11 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error>;
12}
13
14pub trait Mp4VersionedWritable<F: FlagTrait> {
15 fn required_version(&self) -> u8 {0}
16 fn required_flags(&self) -> F {F::default()}
17 fn versioned_byte_size(&self, version: u8, flags: F) -> usize;
18 fn versioned_write<W: WriteMp4>(&self, version: u8, flags: F, writer: &mut W) -> Result<usize, MP4Error>;
19}
20
21impl<F: FlagTrait, T: Mp4Writable + Send + Sync> Mp4VersionedWritable<F> for T {
22 fn versioned_byte_size(&self, _: u8, _: F) -> usize {
23 self.byte_size()
24 }
25 fn versioned_write<W: WriteMp4>(&self, _: u8, _: F, writer: &mut W) -> Result<usize, MP4Error> {
26 self.write(writer)
27 }
28}
29
30impl Mp4Writable for u8 {
31 fn byte_size(&self) -> usize {
32 1
33 }
34
35 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
36 writer.write_u8(*self)?;
37 Ok(self.byte_size())
38 }
39}
40
41impl Mp4Writable for u16 {
42 fn byte_size(&self) -> usize {
43 2
44 }
45 fn write<W: WriteMp4 + ?Sized>(&self, writer: &mut W) -> Result<usize, MP4Error> {
46 writer.write_u16::<BigEndian>(*self)?;
47 Ok(self.byte_size())
48 }
49}
50
51impl Mp4Writable for u32 {
52 fn byte_size(&self) -> usize {
53 4
54 }
55 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
56 writer.write_u32::<BigEndian>(*self)?;
57 Ok(self.byte_size())
58 }
59}
60
61impl Mp4Writable for u64 {
62 fn byte_size(&self) -> usize {
63 8
64 }
65 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
66 writer.write_u64::<BigEndian>(*self)?;
67 Ok(self.byte_size())
68 }
69}
70
71impl Mp4Writable for i8 {
72 fn byte_size(&self) -> usize {
73 1
74 }
75 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
76 writer.write_i8(*self)?;
77 Ok(self.byte_size())
78 }
79}
80
81impl Mp4Writable for i16 {
82 fn byte_size(&self) -> usize {
83 2
84 }
85 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
86 writer.write_i16::<BigEndian>(*self)?;
87 Ok(self.byte_size())
88 }
89}
90
91impl Mp4Writable for i32 {
92 fn byte_size(&self) -> usize {
93 4
94 }
95 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
96 writer.write_i32::<BigEndian>(*self)?;
97 Ok(self.byte_size())
98 }
99}
100
101impl Mp4Writable for i64 {
102 fn byte_size(&self) -> usize {
103 8
104 }
105 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
106 writer.write_i64::<BigEndian>(*self)?;
107 Ok(self.byte_size())
108 }
109}
110
111impl<T: Mp4Writable + Send + Sync> Mp4Writable for [T] {
112 fn byte_size(&self) -> usize {
113 self.iter().map(Mp4Writable::byte_size).sum()
114 }
115
116 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
117 let mut count = 0;
118 for elem in self {
119 count += elem.write(writer)?;
120 }
121 Ok(count)
122 }
123}
124
125impl<T: Mp4Writable + Send + Sync, const N: usize> Mp4Writable for [T; N] {
126 fn byte_size(&self) -> usize {
127 self.as_slice().byte_size()
128 }
129 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
130 self.as_slice().write(writer)
131 }
132}
133
134impl <T: Mp4Writable + Send + Sync> Mp4Writable for Option<T> {
135 fn byte_size(&self) -> usize {
136 self.iter().map(Mp4Writable::byte_size).sum()
137 }
138 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
139 if let Some(elem) = self {
140 elem.write(writer)
141 } else {
142 Ok(0)
143 }
144 }
145}
146
147impl <T: Mp4Writable + Send + Sync> Mp4Writable for Vec<T> {
148 fn byte_size(&self) -> usize {
149 self.as_slice().byte_size()
150 }
151 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
152 self.as_slice().write(writer)
153 }
154}
155
156pub trait WriteMp4: Write + Sized {
157
158 #[inline]
159 fn write_u24(&mut self, n: u32) -> Result<usize, MP4Error> {
160 WriteBytesExt::write_u24::<BigEndian>(self, n)?;
161 Ok(3)
162 }
163
164 #[inline]
165 fn write_i24(&mut self, n: i32) -> Result<usize, MP4Error> {
166 WriteBytesExt::write_i24::<BigEndian>(self, n)?;
167 Ok(3)
168 }
169}
170
171impl<T: Write> WriteMp4 for T {}