rscache/
extension.rs

1//! Extension traits.
2
3use std::io::{self, Read};
4
5/// Adds easy byte reading onto a [`Read`] instance.
6///
7/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
8pub trait ReadExt: Read {
9    fn read_u8(&mut self) -> io::Result<u8>;
10    fn read_i8(&mut self) -> io::Result<i8>;
11    fn read_u16(&mut self) -> io::Result<u16>;
12    fn read_i16(&mut self) -> io::Result<i16>;
13    fn read_smart_u16(&mut self) -> io::Result<u16>;
14    fn read_u24(&mut self) -> io::Result<u32>;
15    fn read_i24(&mut self) -> io::Result<i32>;
16    fn read_u32(&mut self) -> io::Result<u32>;
17    fn read_i32(&mut self) -> io::Result<i32>;
18    fn read_u64(&mut self) -> io::Result<u64>;
19    fn read_i64(&mut self) -> io::Result<i64>;
20    fn read_u128(&mut self) -> io::Result<u128>;
21    fn read_i128(&mut self) -> io::Result<i128>;
22    fn read_smart(&mut self) -> io::Result<u32>;
23    fn read_string(&mut self) -> io::Result<String>;
24}
25
26impl<T: Read> ReadExt for T {
27    fn read_u8(&mut self) -> io::Result<u8> {
28        let mut buffer = [0; 1];
29        self.read_exact(&mut buffer)?;
30
31        Ok(u8::from_be_bytes(buffer))
32    }
33
34    fn read_i8(&mut self) -> io::Result<i8> {
35        Ok(self.read_u8()? as i8)
36    }
37    
38    fn read_u16(&mut self) -> io::Result<u16> {
39        let mut buffer = [0; 2];
40        self.read_exact(&mut buffer)?;
41
42        Ok(u16::from_be_bytes(buffer))
43    }
44
45    fn read_i16(&mut self) -> io::Result<i16> {
46        Ok(self.read_u16()? as i16)
47    }
48
49    fn read_smart_u16(&mut self) -> io::Result<u16> {
50        let byte = self.read_u8()?;
51
52        if byte < 128 {
53            Ok(byte.wrapping_sub(64) as u16)
54        } else {
55            let value = self.read_u8()?;
56            let mut arr = [0; 2];
57            arr[0] = byte;
58            arr[1] = value;
59
60            let value = u16::from_be_bytes(arr);
61            Ok(value - 0xC000)
62        }
63    }
64    fn read_u24(&mut self) -> io::Result<u32> {
65        let mut buffer = [0; 3];
66        self.read_exact(&mut buffer)?;
67
68        Ok(((buffer[0] as u32) << 16) | ((buffer[1] as u32) << 8) | (buffer[2] as u32))
69    }
70
71    fn read_i24(&mut self) -> io::Result<i32> {
72        Ok(self.read_u24()? as i32)
73    }
74
75    fn read_u32(&mut self) -> io::Result<u32> {
76        let mut buffer = [0; 4];
77        self.read_exact(&mut buffer)?;
78
79        Ok(u32::from_be_bytes(buffer))
80    }
81    
82    fn read_i32(&mut self) -> io::Result<i32> {
83        Ok(self.read_u32()? as i32)
84    }
85
86    fn read_u64(&mut self) -> io::Result<u64> {
87        let mut buffer = [0; 8];
88        self.read_exact(&mut buffer)?;
89
90        Ok(u64::from_be_bytes(buffer))
91    }
92
93    fn read_i64(&mut self) -> io::Result<i64> {
94        Ok(self.read_u64()? as i64)
95    }
96
97    fn read_u128(&mut self) -> io::Result<u128> {
98        let mut buffer = [0; 16];
99        self.read_exact(&mut buffer)?;
100
101        Ok(u128::from_be_bytes(buffer))
102    }
103
104    fn read_i128(&mut self) -> io::Result<i128> {
105        Ok(self.read_u128()? as i128)
106    }
107
108    // clean this up.
109    // can't find a way to peek the first byte, even
110    // an iterator reads the first byte...
111    fn read_smart(&mut self) -> io::Result<u32> {
112        let byte = self.read_u8()?;
113
114        if (byte as i64 ^ 0xffffffff) as i8 <= -1 {
115            let value = self.read_u8()?;
116            let mut arr = [0; 2];
117            arr[0] = byte;
118            arr[1] = value;
119
120            return Ok(u16::from_be_bytes(arr) as u32);
121        }
122
123        let mut buffer = [0; 3];
124        self.read_exact(&mut buffer)?;
125        let mut arr = [0; 4];
126        arr[0] = byte;
127        arr[1] = buffer[0];
128        arr[2] = buffer[1];
129        arr[3] = buffer[2];
130
131        Ok(u32::from_be_bytes(arr) & 0x7fffffff)
132    }
133
134    fn read_string(&mut self) -> io::Result<String> {
135        let mut bytes = Vec::new();
136        loop {
137            let byte = self.read_u8()?;
138            if byte != 0 {
139                bytes.push(byte);
140            } else {
141                break;
142            }
143        }
144        Ok(String::from_utf8_lossy(&bytes[..]).to_string())
145    }
146}