remarkable_lines/
bitreader.rs

1use std::io::{Cursor, Read};
2
3use crate::{ParseError, ParseErrorKind};
4
5pub trait Readable: Read + AsRef<[u8]> {}
6impl<T: Read + AsRef<[u8]>> Readable for T {}
7
8/// A little endian binary reader
9pub struct Bitreader<N: Readable> {
10    cursor: Cursor<N>,
11}
12
13impl<N: Readable> Bitreader<N> {
14    pub fn new(bits: N) -> Bitreader<N> {
15        Bitreader {
16            cursor: Cursor::new(bits),
17        }
18    }
19
20    /// End Of File, returns true if not more bytes can be read
21    pub fn eof(&mut self) -> Result<bool, ParseError> {
22        let pos = self.position();
23        match self.read_bytes(1) {
24            Ok(_) => {
25                self.set_position(pos);
26                Ok(false)
27            }
28            Err(e) => {
29                // if an io error occurs we assume no more bytes can be read, aka eof
30                if e.kind == ParseErrorKind::Io {
31                    self.set_position(pos);
32                    return Ok(true);
33                }
34                return Err(e);
35            }
36        }
37    }
38
39    pub fn position(&self) -> u64 {
40        self.cursor.position()
41    }
42
43    pub fn set_position(&mut self, position: u64) {
44        self.cursor.set_position(position);
45        // self.cursor.seek(SeekFrom::Current(position)).unwrap();
46    }
47
48    // Read bytes first from inner buffer than from bits, will also update the offset
49    fn read_exact(&mut self, buffer: &mut [u8]) -> Result<(), ParseError> {
50        self.cursor.read_exact(buffer)?;
51
52        return Ok(());
53    }
54
55    pub fn read_bytes(&mut self, amount: usize) -> Result<Vec<u8>, ParseError> {
56        let mut buffer = vec![0; amount];
57        self.read_exact(&mut buffer)?;
58        return Ok(buffer);
59    }
60
61    pub fn read_string(&mut self, length: usize) -> Result<String, ParseError> {
62        return Ok(String::from_utf8(self.read_bytes(length)?)
63            .map_err(|_| ParseError::invalid("String contains invalid utf-8"))?);
64    }
65
66    // https://en.wikipedia.org/wiki/Variable-length_quantity
67    pub fn read_varuint(&mut self) -> Result<u32, ParseError> {
68        let mut shift = 0;
69        let mut result = 0;
70        let mut i;
71        loop {
72            i = self.read_u8()?;
73            result |= ((i & 0x7F) << shift) as u32;
74            shift += 7;
75            if i & 0x80 == 0 {
76                break;
77            }
78        }
79        return Ok(result);
80    }
81
82    pub fn read_bool(&mut self) -> Result<bool, ParseError> {
83        return Ok(self.read_u8()? > 0);
84    }
85
86    pub fn read_f32(&mut self) -> Result<f32, ParseError> {
87        let mut buffer = [0; 4];
88        self.read_exact(&mut buffer)?;
89        return Ok(f32::from_le_bytes(buffer));
90    }
91
92    pub fn read_f64(&mut self) -> Result<f64, ParseError> {
93        let mut buffer = [0; 8];
94        self.read_exact(&mut buffer)?;
95        return Ok(f64::from_le_bytes(buffer));
96    }
97
98    pub fn read_u8(&mut self) -> Result<u8, ParseError> {
99        let mut buffer = [0];
100        self.read_exact(&mut buffer)?;
101        return Ok(u8::from_le_bytes(buffer));
102    }
103
104    pub fn read_u16(&mut self) -> Result<u16, ParseError> {
105        let mut buffer = [0; 2];
106        self.read_exact(&mut buffer)?;
107        return Ok(u16::from_le_bytes(buffer));
108    }
109
110    pub fn read_u32(&mut self) -> Result<u32, ParseError> {
111        let mut buffer = [0; 4];
112        self.read_exact(&mut buffer)?;
113        return Ok(u32::from_le_bytes(buffer));
114    }
115
116    /// Parse uuid from data in little endian format
117    /// Using Variant 2 UUID's with mixed endianess <https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding>
118    pub fn read_uuid(&mut self) -> Result<String, ParseError> {
119        let uuid_length = self.read_varuint()?;
120        if uuid_length != 16 {
121            return Err(ParseError::invalid("Expected UUID length to be 16 bytes"));
122        }
123
124        let mut uuid_bytes: Vec<u8> = self.read_bytes(uuid_length as usize)?;
125
126        // Set first 3 uuid sections to big endianness
127        uuid_bytes[..4].reverse();
128        uuid_bytes[4..6].reverse();
129        uuid_bytes[6..8].reverse();
130
131        // put bytes in a single number
132        let uuid_bytes = u128::from_be_bytes(
133            uuid_bytes
134                .try_into()
135                .map_err(|_| ParseError::invalid("Failed to parse uuid bytes into integer"))?,
136        );
137
138        // turn hexidecimals into string
139        let uuid = format!("{uuid_bytes:032x}");
140        // add slashes
141        let uuid = format!(
142            "{}-{}-{}-{}-{}",
143            &uuid[..8],
144            &uuid[8..12],
145            &uuid[12..16],
146            &uuid[16..20],
147            &uuid[20..],
148        );
149
150        Ok(uuid)
151    }
152}
153
154// #[test]
155// fn test_read_uuid() {
156//     let a: u128 = 0x495ba59fc9432b5cb4553682f6948906;
157//     Bitreader::new(&a.to_le_bytes())
158// }
159//