swf/
extensions.rs

1use crate::error::Result;
2use crate::string::SwfStr;
3use byteorder::{LittleEndian, ReadBytesExt};
4use std::io;
5
6pub trait ReadSwfExt<'a> {
7    fn as_mut_slice(&mut self) -> &mut &'a [u8];
8
9    fn as_slice(&self) -> &'a [u8];
10
11    fn pos(&self, data: &[u8]) -> usize {
12        self.as_slice().as_ptr() as usize - data.as_ptr() as usize
13    }
14
15    // TODO: Make this fallible?
16    fn seek(&mut self, data: &'a [u8], relative_offset: isize) {
17        let pos = self.pos(data);
18        let pos = (pos as isize + relative_offset) as usize;
19        let pos = pos.min(data.len());
20        *self.as_mut_slice() = &data[pos..];
21    }
22
23    fn seek_absolute(&mut self, data: &'a [u8], pos: usize) {
24        let pos = pos.min(data.len());
25        *self.as_mut_slice() = &data[pos..];
26    }
27
28    #[inline]
29    fn read_u8(&mut self) -> Result<u8> {
30        Ok(ReadBytesExt::read_u8(self.as_mut_slice())?)
31    }
32
33    #[inline]
34    fn read_u16(&mut self) -> Result<u16> {
35        Ok(ReadBytesExt::read_u16::<LittleEndian>(self.as_mut_slice())?)
36    }
37
38    #[inline]
39    fn read_u32(&mut self) -> Result<u32> {
40        Ok(ReadBytesExt::read_u32::<LittleEndian>(self.as_mut_slice())?)
41    }
42
43    #[inline]
44    fn read_u64(&mut self) -> Result<u64> {
45        Ok(ReadBytesExt::read_u64::<LittleEndian>(self.as_mut_slice())?)
46    }
47
48    #[inline]
49    fn read_i8(&mut self) -> Result<i8> {
50        Ok(ReadBytesExt::read_i8(self.as_mut_slice())?)
51    }
52
53    #[inline]
54    fn read_i16(&mut self) -> Result<i16> {
55        Ok(ReadBytesExt::read_i16::<LittleEndian>(self.as_mut_slice())?)
56    }
57
58    #[inline]
59    fn read_i32(&mut self) -> Result<i32> {
60        Ok(ReadBytesExt::read_i32::<LittleEndian>(self.as_mut_slice())?)
61    }
62
63    #[inline]
64    fn read_f32(&mut self) -> Result<f32> {
65        Ok(ReadBytesExt::read_f32::<LittleEndian>(self.as_mut_slice())?)
66    }
67
68    #[inline]
69    fn read_f64(&mut self) -> Result<f64> {
70        Ok(ReadBytesExt::read_f64::<LittleEndian>(self.as_mut_slice())?)
71    }
72
73    #[inline]
74    fn read_encoded_u32(&mut self) -> Result<u32> {
75        let mut val: u32 = 0;
76        for i in (0..35).step_by(7) {
77            let byte = self.read_u8()? as u32;
78            val |= (byte & 0b0111_1111) << i;
79            if byte & 0b1000_0000 == 0 {
80                break;
81            }
82        }
83        Ok(val)
84    }
85
86    fn read_slice(&mut self, len: usize) -> Result<&'a [u8]> {
87        let slice = self.as_mut_slice();
88        if slice.len() >= len {
89            let new_slice = &slice[..len];
90            *slice = &slice[len..];
91            Ok(new_slice)
92        } else {
93            Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Not enough data for slice").into())
94        }
95    }
96
97    fn read_slice_to_end(&mut self) -> &'a [u8] {
98        let slice = self.as_mut_slice();
99        let res = &slice[..];
100        *slice = &[];
101        res
102    }
103
104    #[inline]
105    fn read_str(&mut self) -> Result<&'a SwfStr> {
106        let slice = self.as_mut_slice();
107        let s = SwfStr::from_bytes_null_terminated(slice).ok_or_else(|| {
108            io::Error::new(io::ErrorKind::UnexpectedEof, "Not enough data for string")
109        })?;
110        *slice = &slice[s.len() + 1..];
111        Ok(s)
112    }
113
114    #[inline]
115    fn read_str_with_len(&mut self) -> Result<&'a SwfStr> {
116        let len = self.read_u8()?;
117        let bytes = &self.read_slice(len.into())?;
118        // TODO: Maybe just strip the possible trailing null char instead of looping here.
119        Ok(SwfStr::from_bytes_null_terminated(bytes).unwrap_or_else(|| SwfStr::from_bytes(bytes)))
120    }
121}