symphonia_metadata/id3v2/
unsync.rs1use std::io;
9
10use symphonia_core::errors::Result;
11use symphonia_core::io::{FiniteStream, ReadBytes};
12
13pub fn read_syncsafe_leq32<B: ReadBytes>(reader: &mut B, bit_width: u8) -> Result<u32> {
14 debug_assert!(bit_width <= 32);
15
16 let mut result = 0u32;
17 let mut bits_read = 0;
18
19 while bits_read < bit_width {
20 let next_read = (bit_width - bits_read).min(7);
22 bits_read += next_read;
23 let mask = (1 << next_read) - 1;
25 result |= u32::from(reader.read_u8()? & mask) << (bit_width - bits_read);
26 }
27
28 Ok(result)
29}
30
31pub fn decode_unsynchronisation(buf: &mut [u8]) -> &mut [u8] {
32 let len = buf.len();
33 let mut src = 0;
34 let mut dst = 0;
35
36 while src < len - 1 {
38 buf[dst] = buf[src];
39 dst += 1;
40 src += 1;
41
42 if buf[src - 1] == 0xff && buf[src] == 0x00 {
43 src += 1;
44 }
45 }
46
47 if src < len {
48 buf[dst] = buf[src];
49 dst += 1;
50 }
51
52 &mut buf[..dst]
53}
54
55pub struct UnsyncStream<B: ReadBytes + FiniteStream> {
56 inner: B,
57 byte: u8,
58}
59
60impl<B: ReadBytes + FiniteStream> UnsyncStream<B> {
61 pub fn new(inner: B) -> Self {
62 UnsyncStream { inner, byte: 0 }
63 }
64
65 pub fn into_inner(self) -> B {
67 self.inner
68 }
69}
70
71impl<B: ReadBytes + FiniteStream> FiniteStream for UnsyncStream<B> {
72 #[inline(always)]
73 fn byte_len(&self) -> u64 {
74 self.inner.byte_len()
75 }
76
77 #[inline(always)]
78 fn bytes_read(&self) -> u64 {
79 self.inner.bytes_read()
80 }
81
82 #[inline(always)]
83 fn bytes_available(&self) -> u64 {
84 self.inner.bytes_available()
85 }
86}
87
88impl<B: ReadBytes + FiniteStream> ReadBytes for UnsyncStream<B> {
89 fn read_byte(&mut self) -> io::Result<u8> {
90 let last = self.byte;
91
92 self.byte = self.inner.read_byte()?;
93
94 if last == 0xff && self.byte == 0x00 {
97 self.byte = self.inner.read_byte()?;
98 }
99
100 Ok(self.byte)
101 }
102
103 fn read_double_bytes(&mut self) -> io::Result<[u8; 2]> {
104 Ok([self.read_byte()?, self.read_byte()?])
105 }
106
107 fn read_triple_bytes(&mut self) -> io::Result<[u8; 3]> {
108 Ok([self.read_byte()?, self.read_byte()?, self.read_byte()?])
109 }
110
111 fn read_quad_bytes(&mut self) -> io::Result<[u8; 4]> {
112 Ok([self.read_byte()?, self.read_byte()?, self.read_byte()?, self.read_byte()?])
113 }
114
115 fn read_buf(&mut self, _: &mut [u8]) -> io::Result<usize> {
116 unimplemented!();
118 }
119
120 fn read_buf_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
121 let len = buf.len();
122
123 if len > 0 {
124 self.inner.read_buf_exact(buf)?;
126
127 let mut src = usize::from(self.byte == 0xff && buf[0] == 0x00);
130 let mut dst = 0;
131
132 self.byte = buf[len - 1];
134
135 while src < len - 1 {
137 buf[dst] = buf[src];
138 dst += 1;
139 src += 1;
140
141 if buf[src - 1] == 0xff && buf[src] == 0x00 {
142 src += 1;
143 }
144 }
145
146 if src < len {
149 buf[dst] = buf[src];
150 dst += 1;
151 }
152
153 while dst < len {
156 buf[dst] = self.read_byte()?;
157 dst += 1;
158 }
159 }
160
161 Ok(())
162 }
163
164 fn scan_bytes_aligned<'a>(
165 &mut self,
166 _: &[u8],
167 _: usize,
168 _: &'a mut [u8],
169 ) -> io::Result<&'a mut [u8]> {
170 unimplemented!();
172 }
173
174 fn ignore_bytes(&mut self, count: u64) -> io::Result<()> {
175 for _ in 0..count {
176 self.inner.read_byte()?;
177 }
178 Ok(())
179 }
180
181 fn pos(&self) -> u64 {
182 unimplemented!();
184 }
185}
186
187#[cfg(test)]
188mod tests {
189 use super::read_syncsafe_leq32;
190 use symphonia_core::io::BufReader;
191
192 #[test]
193 fn verify_read_syncsafe_leq32() {
194 let mut stream = BufReader::new(&[3, 4, 80, 1, 15]);
195 assert_eq!(101875743, read_syncsafe_leq32(&mut stream, 32).unwrap());
196
197 let mut stream = BufReader::new(&[16, 16, 16, 16, 16]);
202 assert_eq!(541098240, read_syncsafe_leq32(&mut stream, 32).unwrap());
203
204 let mut stream = BufReader::new(&[3, 4, 80, 1]);
205 assert_eq!(6367233, read_syncsafe_leq32(&mut stream, 28).unwrap());
206
207 let mut stream = BufReader::new(&[3, 4, 80, 1]);
208 assert_eq!(0, read_syncsafe_leq32(&mut stream, 0).unwrap());
209 }
210}