bytestream_rs/
reader.rs

1use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
2use flate2::read::ZlibDecoder;
3use std::io::Read;
4
5use crate::bytestream::{ByteStream, ByteStreamError};
6use crate::logiclong::LogicLong;
7
8impl ByteStream {
9    // read a byte from the buffer
10    pub fn read_byte(&mut self) -> Result<u8, ByteStreamError> {
11        let byte = self.cursor.read_u8()?;
12        Ok(byte)
13    }
14
15    // read bool will read a byte and return true and the value of the byte if it is > 0, or false and 0 if it is 0
16    pub fn read_bool(&mut self) -> Result<(bool, u8), ByteStreamError> {
17        let byte = self.read_byte()?;
18        let bool = byte > 0;
19        self.message += format!("(Bool): {} ({})\n", bool, byte).as_str();
20        Ok((bool, byte))
21    }
22
23    // read n bytes from the buffer if possible, and return a reference to the bytes
24    pub fn read_bytes(&mut self, n: usize) -> Result<Vec<u8>, ByteStreamError> {
25        // let mut bytes = Vec::new();
26        (0..n).map(|_| self.read_byte()).collect()
27    }
28
29    // read int8 will read a byte and return the value of the byte
30    pub fn read_int8(&mut self) -> Result<i8, ByteStreamError> {
31        let int8 = self.cursor.read_i8()?;
32        self.message += format!("(Int8): {}\n", int8).as_str();
33        Ok(int8)
34    }
35
36    // read uint8 will read a byte and return the value of the byte
37    pub fn read_uint8(&mut self) -> Result<u8, ByteStreamError> {
38        let uint8 = self.cursor.read_u8()?;
39        self.message += format!("(UInt8): {}\n", uint8).as_str();
40        Ok(uint8)
41    }
42
43    // read int16 will read 2 bytes and return the value of the bytes
44    pub fn read_int16(&mut self) -> Result<i16, ByteStreamError> {
45        let int16 = self.cursor.read_i16::<BigEndian>()?;
46        self.message += format!("(Int16): {}\n", int16).as_str();
47        Ok(int16)
48    }
49
50    // read uint16 will read 2 bytes and return the value of the bytes
51    pub fn read_uint16(&mut self) -> Result<u16, ByteStreamError> {
52        let uint16 = self.cursor.read_u16::<BigEndian>()?;
53        self.message += format!("(UInt16): {}\n", uint16).as_str();
54        Ok(uint16)
55    }
56
57    // read int24 will read 3 bytes and return the value of the bytes as an i32
58    pub fn read_int24(&mut self) -> Result<i32, ByteStreamError> {
59        let int24 = self.cursor.read_i24::<BigEndian>()?;
60        self.message += format!("(Int24): {}\n", int24).as_str();
61        Ok(int24)
62    }
63
64    // read uint24 will read 3 bytes and return the value of the bytes as a u32
65    pub fn read_uint24(&mut self) -> Result<u32, ByteStreamError> {
66        let uint24 = self.cursor.read_u24::<BigEndian>()?;
67        self.message += format!("(UInt24): {}\n", uint24).as_str();
68        Ok(uint24)
69    }
70
71    // read int32 will read 4 bytes and return the value of the bytes as an i32
72    pub fn read_int32(&mut self) -> Result<i32, ByteStreamError> {
73        let int32 = self.cursor.read_i32::<BigEndian>()?;
74        self.message += format!("(Int32): {}\n", int32).as_str();
75        Ok(int32)
76    }
77
78    // read int32LE will read 4 bytes and return the value of the bytes as an i32 in little endian
79    pub fn read_int32_le(&mut self) -> Result<i32, ByteStreamError> {
80        let int32 = self.cursor.read_i32::<LittleEndian>()?;
81        // self.message += format!("(Int32LE): {}\n", int32).as_str();
82        Ok(int32)
83    }
84
85    // read uint32 will read 4 bytes and return the value of the bytes as a u32
86    pub fn read_uint32(&mut self) -> Result<u32, ByteStreamError> {
87        let uint32 = self.cursor.read_u32::<BigEndian>()?;
88        self.message += format!("(UInt32): {}\n", uint32).as_str();
89        Ok(uint32)
90    }
91
92    // read int64 will read a byte and return the value of the byte as an i64
93    pub fn read_int64(&mut self) -> Result<i64, ByteStreamError> {
94        let int64 = self.cursor.read_i64::<BigEndian>()?;
95        self.message += format!("(Int64): {}\n", int64).as_str();
96        Ok(int64)
97    }
98
99    // read uint64 will read 8 bytes and return the value of the bytes as a u64
100    pub fn read_uint64(&mut self) -> Result<u64, ByteStreamError> {
101        let uint64 = self.cursor.read_u64::<BigEndian>()?;
102        self.message += format!("(UInt64): {}\n", uint64).as_str();
103        Ok(uint64)
104    }
105
106    // read varint will read as many bytes as necessary to read a varint and return the value of the varint as an i64
107    pub fn read_vint(&mut self) -> Result<i64, ByteStreamError> {
108        let b = self.read_byte()? as i64;
109        let sign = (b >> 6) & 1;
110        let mut i = b & 0x3F;
111        let mut offset = 6 as i64;
112
113        for _ in 0..4 {
114            if (b & 0x80) != 0 {
115                let b = self.read_byte()? as i64;
116                i |= (b & 0x7F) << offset;
117                offset += 7;
118            } else {
119                break;
120            }
121        }
122
123        let vint = if b & 0x80 != 0 {
124            -1
125        } else {
126            if sign == 1 && offset < 32 {
127                i | (i | (0xFFFFFFFF << offset))
128            } else {
129                i
130            }
131        };
132        self.message += format!("(VInt): {}\n", vint).as_str();
133        Ok(vint)
134        // Ok(if (b & 0x80) != 0 {
135        //     -1
136        // } else {
137        //     if sign == 1 && offset < 32 {
138        //         i | (i | (0xFFFFFFFF << offset))
139        //     } else {
140        //         i
141        //     }
142        // })
143    }
144
145    // read long = read int64
146    pub fn read_long(&mut self) -> Result<i64, ByteStreamError> {
147        let long = self.cursor.read_i64::<BigEndian>()?;
148        self.message += format!("(Long): {}\n", long).as_str();
149        Ok(long)
150    }
151
152    // read ulong = read uint64
153    pub fn read_ulong(&mut self) -> Result<u64, ByteStreamError> {
154        let ulong = self.cursor.read_u64::<BigEndian>()?;
155        self.message += format!("(ULong): {}\n", ulong).as_str();
156        Ok(ulong)
157    }
158
159    // read longlong = read int64
160    pub fn read_longlong(&mut self) -> Result<i64, ByteStreamError> {
161        let longlong = self.cursor.read_i64::<BigEndian>()?;
162        self.message += format!("(LongLong): {}\n", longlong).as_str();
163        Ok(longlong)
164    }
165
166    // read ulonglong = read uint64
167    pub fn read_ulonglong(&mut self) -> Result<u64, ByteStreamError> {
168        let ulonglong = self.cursor.read_u64::<BigEndian>()?;
169        self.message += format!("(ULongLong): {}\n", ulonglong).as_str();
170        Ok(ulonglong)
171    }
172
173    // read string will read a 4 byte i32 (n) declaring the length of the string, and then read n bytes from the buffer as a string
174    pub fn read_string(&mut self) -> Result<String, ByteStreamError> {
175        // read int32, then read that many bytes as a string
176        let length = self.cursor.read_i32::<BigEndian>()?;
177        if length < -1 {
178            return Err(ByteStreamError::InvalidStringLength(length as usize));
179        } else if length == 0 || length == -1 {
180            self.message += "(String): \n";
181            return Ok(String::new());
182        }
183
184        let mut bytes = vec![0; length as usize];
185        self.cursor.read_exact(&mut bytes)?;
186        let str =
187            String::from_utf8(bytes).map_err(|e| ByteStreamError::InvalidString(e.to_string()))?;
188        self.message += format!("(String): {}\n", str).as_str();
189        Ok(str)
190    }
191
192    // read string_reference = read string
193    pub fn read_string_reference(&mut self) -> Result<String, ByteStreamError> {
194        // read int32, then read that many bytes, same for reading but different when writing
195        let length = self.cursor.read_i32::<BigEndian>()?;
196        if length < -1 {
197            return Err(ByteStreamError::InvalidStringLength(length as usize));
198        } else if length == 0 || length == -1 {
199            self.message += "(StringReference): \n";
200            return Ok(String::new());
201        }
202
203        let mut bytes = vec![0; length as usize];
204        self.cursor.read_exact(&mut bytes)?;
205        let str =
206            String::from_utf8(bytes).map_err(|e| ByteStreamError::InvalidString(e.to_string()))?;
207        self.message += format!("(StringReference): {}\n", str).as_str();
208        Ok(str)
209    }
210
211    // read string size will read a string given the size already
212    pub fn read_string_size(&mut self, size: usize) -> Result<String, ByteStreamError> {
213        // read size bytes as a string
214        let mut bytes = vec![0; size];
215        self.cursor.read_exact(&mut bytes)?;
216        let str =
217            String::from_utf8(bytes).map_err(|e| ByteStreamError::InvalidString(e.to_string()))?;
218        self.message += format!("(StringSize): {}\n", str).as_str();
219        Ok(str)
220    }
221
222    // read compressed_string reads a 4 byte compressed length, 4 byte LE uncompressed length,
223    // reads the compressed string, and then decompresses it
224    pub fn read_compressed_string(&mut self) -> Result<String, ByteStreamError> {
225        let compressed_size = self.cursor.read_i32::<BigEndian>()?;
226        // let _uncompressed_size = self.cursor.read_i32::<LittleEndian>()?;
227        let compressed_bytes = self.read_bytes(compressed_size as usize)?;
228
229        let _uncompressed_size = i32::from_be_bytes(
230            compressed_bytes[0..4]
231                .try_into()
232                .map_err(|_| ByteStreamError::NotEnoughBytes)?,
233        );
234        let mut decompressor = ZlibDecoder::new(&compressed_bytes[4..]);
235        let mut data = String::new();
236        decompressor.read_to_string(&mut data)?;
237        self.message += format!("(CompressedString): {}\n", data).as_str();
238        Ok(data)
239    }
240
241    // custom 2 4 byte ints that represent a game player tag, see logiclong.rs for more info
242    pub fn read_logic_long(&mut self) -> Result<LogicLong, ByteStreamError> {
243        let (low, high) = (
244            self.cursor.read_u32::<BigEndian>()?,
245            self.cursor.read_u32::<BigEndian>()?,
246        );
247        let logic_long = LogicLong::new(low, high);
248        self.message += format!("(LogicLong): {}\n", logic_long).as_str();
249        Ok(LogicLong::new(low, high))
250    }
251}