/src/mp4san/webpsan/src/parse/integers.rs
Line | Count | Source |
1 | | #![allow(missing_docs)] |
2 | | |
3 | | use std::mem::size_of; |
4 | | use std::num::NonZeroU32; |
5 | | |
6 | | use bitflags::Flags; |
7 | | use bytes::{Buf, BufMut}; |
8 | | |
9 | | use mediasan_common::error::WhileParsingType; |
10 | | use mediasan_common::parse::FourCC; |
11 | | use mediasan_common::{ensure_attach, report_attach, Result, ResultExt}; |
12 | | |
13 | | use super::ParseError; |
14 | | |
15 | | pub trait WebmPrim: Sized { |
16 | | const ENCODED_LEN: u32; |
17 | | fn parse<B: Buf>(buf: B) -> Result<Self, ParseError>; |
18 | | fn put_buf<B: BufMut>(&self, buf: B); |
19 | | } |
20 | | |
21 | | pub trait WebmFlags: Flags {} |
22 | | |
23 | | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] |
24 | | pub struct U24(u32); |
25 | | |
26 | | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] |
27 | | pub struct OneBasedU24(NonZeroU32); |
28 | | |
29 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
30 | | pub struct Reserved<const LEN: u32>(()); |
31 | | |
32 | | // |
33 | | // WebMPrim impls |
34 | | // |
35 | | |
36 | | macro_rules! webm_int { |
37 | | ($($ty:ty => ($get_fun:ident, $put_fun:ident)),+ $(,)?) => { |
38 | | $(impl WebmPrim for $ty { |
39 | | |
40 | | const ENCODED_LEN: u32 = size_of::<Self>() as u32; |
41 | | |
42 | 1.39k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { |
43 | 1.39k | ensure_attach!( |
44 | 1.39k | buf.remaining() >= Self::ENCODED_LEN as usize, |
45 | 0 | ParseError::TruncatedChunk, |
46 | 0 | WhileParsingType::new::<Self>(), |
47 | | ); |
48 | 1.39k | Ok(buf.$get_fun()) |
49 | 1.39k | } <u16 as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut> Line | Count | Source | 42 | 699 | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { | 43 | 699 | ensure_attach!( | 44 | 699 | buf.remaining() >= Self::ENCODED_LEN as usize, | 45 | 0 | ParseError::TruncatedChunk, | 46 | 0 | WhileParsingType::new::<Self>(), | 47 | | ); | 48 | 699 | Ok(buf.$get_fun()) | 49 | 699 | } |
<u32 as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut> Line | Count | Source | 42 | 699 | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { | 43 | 699 | ensure_attach!( | 44 | 699 | buf.remaining() >= Self::ENCODED_LEN as usize, | 45 | 0 | ParseError::TruncatedChunk, | 46 | 0 | WhileParsingType::new::<Self>(), | 47 | | ); | 48 | 699 | Ok(buf.$get_fun()) | 49 | 699 | } |
|
50 | | |
51 | 0 | fn put_buf<B: BufMut>(&self, mut buf: B) { |
52 | 0 | buf.$put_fun(*self) |
53 | 0 | } Unexecuted instantiation: <u16 as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut> Unexecuted instantiation: <u32 as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut> |
54 | | })+ |
55 | | }; |
56 | | } |
57 | | |
58 | | webm_int! { |
59 | | u8 => (get_u8, put_u8), |
60 | | u16 => (get_u16, put_u16_le), |
61 | | u32 => (get_u32_le, put_u32_le), |
62 | | u64 => (get_u64_le, put_u64_le), |
63 | | i8 => (get_i8, put_i8), |
64 | | i16 => (get_i16_le, put_i16_le), |
65 | | i32 => (get_i32_le, put_i32_le), |
66 | | i64 => (get_i64_le, put_i64_le), |
67 | | } |
68 | | |
69 | | impl WebmPrim for FourCC { |
70 | | const ENCODED_LEN: u32 = 4; |
71 | | |
72 | | fn parse<B: Buf>(buf: B) -> Result<Self, ParseError> { |
73 | | ensure_attach!( |
74 | | buf.remaining() >= Self::ENCODED_LEN as usize, |
75 | | ParseError::TruncatedChunk, |
76 | | WhileParsingType::new::<Self>(), |
77 | | ); |
78 | | Ok(FourCC::parse(buf)) |
79 | | } |
80 | | |
81 | | fn put_buf<B: BufMut>(&self, buf: B) { |
82 | | FourCC::put_buf(self, buf) |
83 | | } |
84 | | } |
85 | | |
86 | | // |
87 | | // WebmFlags impls |
88 | | // |
89 | | |
90 | | impl<T: WebmFlags> WebmPrim for T |
91 | | where |
92 | | T::Bits: TryFrom<u64> + Into<u64>, |
93 | | { |
94 | | const ENCODED_LEN: u32 = size_of::<<Self as Flags>::Bits>() as u32; |
95 | | |
96 | 11.6k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { |
97 | 11.6k | ensure_attach!( |
98 | 11.6k | buf.remaining() >= Self::ENCODED_LEN as usize, |
99 | 0 | ParseError::TruncatedChunk, |
100 | 0 | WhileParsingType::new::<Self>(), |
101 | | ); |
102 | 11.6k | let value = buf.get_uint_le(Self::ENCODED_LEN as usize); |
103 | 11.6k | let value = value.try_into().unwrap_or_else(|_| unreachable!()); Unexecuted instantiation: <webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut bytes::bytes_mut::BytesMut>::{closure#0}Unexecuted instantiation: <webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#0}Unexecuted instantiation: <webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#0} |
104 | 11.6k | Self::from_bits(value) |
105 | 11.6k | .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits")) <webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut bytes::bytes_mut::BytesMut>::{closure#1}Line | Count | Source | 105 | 14 | .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits")) |
<webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#1}Line | Count | Source | 105 | 19 | .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits")) |
<webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#1}Line | Count | Source | 105 | 6 | .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits")) |
|
106 | 11.6k | .while_parsing_type() |
107 | 11.6k | } <webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut> Line | Count | Source | 96 | 5.74k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { | 97 | 5.74k | ensure_attach!( | 98 | 5.74k | buf.remaining() >= Self::ENCODED_LEN as usize, | 99 | 0 | ParseError::TruncatedChunk, | 100 | 0 | WhileParsingType::new::<Self>(), | 101 | | ); | 102 | 5.74k | let value = buf.get_uint_le(Self::ENCODED_LEN as usize); | 103 | 5.74k | let value = value.try_into().unwrap_or_else(|_| unreachable!()); | 104 | 5.74k | Self::from_bits(value) | 105 | 5.74k | .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits")) | 106 | 5.74k | .while_parsing_type() | 107 | 5.74k | } |
<webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut bytes::bytes_mut::BytesMut> Line | Count | Source | 96 | 2.41k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { | 97 | 2.41k | ensure_attach!( | 98 | 2.41k | buf.remaining() >= Self::ENCODED_LEN as usize, | 99 | 0 | ParseError::TruncatedChunk, | 100 | 0 | WhileParsingType::new::<Self>(), | 101 | | ); | 102 | 2.41k | let value = buf.get_uint_le(Self::ENCODED_LEN as usize); | 103 | 2.41k | let value = value.try_into().unwrap_or_else(|_| unreachable!()); | 104 | 2.41k | Self::from_bits(value) | 105 | 2.41k | .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits")) | 106 | 2.41k | .while_parsing_type() | 107 | 2.41k | } |
<webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut> Line | Count | Source | 96 | 3.44k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { | 97 | 3.44k | ensure_attach!( | 98 | 3.44k | buf.remaining() >= Self::ENCODED_LEN as usize, | 99 | 0 | ParseError::TruncatedChunk, | 100 | 0 | WhileParsingType::new::<Self>(), | 101 | | ); | 102 | 3.44k | let value = buf.get_uint_le(Self::ENCODED_LEN as usize); | 103 | 3.44k | let value = value.try_into().unwrap_or_else(|_| unreachable!()); | 104 | 3.44k | Self::from_bits(value) | 105 | 3.44k | .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits")) | 106 | 3.44k | .while_parsing_type() | 107 | 3.44k | } |
|
108 | | |
109 | 0 | fn put_buf<B: BufMut>(&self, mut buf: B) { |
110 | 0 | buf.put_uint(self.bits().into(), Self::ENCODED_LEN as usize); |
111 | 0 | } Unexecuted instantiation: <webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut> Unexecuted instantiation: <webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::put_buf::<&mut dyn bytes::buf::buf_mut::BufMut> Unexecuted instantiation: <webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut> |
112 | | } |
113 | | |
114 | | // |
115 | | // U24 impls |
116 | | // |
117 | | |
118 | | impl U24 { |
119 | 11.4k | pub fn get(&self) -> u32 { |
120 | 11.4k | self.0 |
121 | 11.4k | } |
122 | | } |
123 | | |
124 | | impl WebmPrim for U24 { |
125 | | const ENCODED_LEN: u32 = 3; |
126 | | |
127 | 17.2k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { |
128 | 17.2k | ensure_attach!( |
129 | 17.2k | buf.remaining() >= Self::ENCODED_LEN as usize, |
130 | 0 | ParseError::TruncatedChunk, |
131 | 0 | WhileParsingType::new::<Self>(), |
132 | | ); |
133 | 17.2k | Ok(Self(buf.get_uint_le(Self::ENCODED_LEN as usize) as u32)) |
134 | 17.2k | } |
135 | | |
136 | 0 | fn put_buf<B: BufMut>(&self, mut buf: B) { |
137 | 0 | buf.put_uint_le(self.0.into(), Self::ENCODED_LEN as usize) |
138 | 0 | } |
139 | | } |
140 | | |
141 | | // |
142 | | // OneBasedU24 impls |
143 | | // |
144 | | |
145 | | impl OneBasedU24 { |
146 | 31.5k | pub fn get(&self) -> NonZeroU32 { |
147 | 31.5k | self.0 |
148 | 31.5k | } |
149 | | } |
150 | | |
151 | | impl WebmPrim for OneBasedU24 { |
152 | | const ENCODED_LEN: u32 = 3; |
153 | | |
154 | 18.3k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { |
155 | 18.3k | ensure_attach!( |
156 | 18.3k | buf.remaining() >= Self::ENCODED_LEN as usize, |
157 | 0 | ParseError::TruncatedChunk, |
158 | 0 | WhileParsingType::new::<Self>(), |
159 | | ); |
160 | 18.3k | let value = NonZeroU32::MIN.saturating_add(buf.get_uint_le(Self::ENCODED_LEN as usize) as u32); |
161 | 18.3k | Ok(Self(value)) |
162 | 18.3k | } |
163 | | |
164 | 0 | fn put_buf<B: BufMut>(&self, mut buf: B) { |
165 | 0 | buf.put_uint_le(u64::from(self.0.get()) - 1, Self::ENCODED_LEN as usize); |
166 | 0 | } |
167 | | } |
168 | | |
169 | | // |
170 | | // Reserved impls |
171 | | // |
172 | | |
173 | | impl<const LEN: u32> WebmPrim for Reserved<LEN> { |
174 | | const ENCODED_LEN: u32 = LEN; |
175 | | |
176 | 3.44k | fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> { |
177 | 13.7k | for _ in 0..LEN { |
178 | 10.3k | ensure_attach!( |
179 | 10.3k | buf.get_u8() == 0, |
180 | 22 | ParseError::InvalidInput, |
181 | | "non-zero reserved bits", |
182 | 22 | WhileParsingType::new::<Self>(), |
183 | | ); |
184 | | } |
185 | 3.42k | Ok(Self(())) |
186 | 3.44k | } |
187 | | |
188 | 0 | fn put_buf<B: BufMut>(&self, mut buf: B) { |
189 | 0 | for _ in 0..LEN { |
190 | 0 | buf.put_u8(0); |
191 | 0 | } |
192 | 0 | } |
193 | | } |