unity_rs/
reader.rs

1use crate::error::{UnityError, UnityResult};
2use crate::math::{Matrix4x4, RectF32, Vector2, Vector3, Vector4};
3
4#[derive(Clone, Copy)]
5pub enum ByteOrder {
6    Big,
7    Little,
8}
9
10#[derive(Clone)]
11pub struct Reader<'a> {
12    buf: &'a [u8],
13    offset: usize,
14    order: ByteOrder,
15}
16
17impl<'a> Reader<'a> {
18    pub fn new(buf: &'a [u8], order: ByteOrder) -> Self {
19        Self { buf, offset: 0, order }
20    }
21
22    pub fn get_offset(&self) -> usize {
23        self.offset
24    }
25
26    pub fn set_offset(&mut self, offset: usize) -> UnityResult<usize> {
27        if self.buf.len() < offset {
28            return Err(UnityError::Eof);
29        }
30        let result = self.offset;
31        self.offset = offset;
32        Ok(result)
33    }
34
35    pub fn set_little_order(&mut self) {
36        self.order = ByteOrder::Little
37    }
38
39    pub fn set_big_order(&mut self) {
40        self.order = ByteOrder::Big
41    }
42
43    pub fn len(&self) -> usize {
44        self.buf.len()
45    }
46
47    pub fn get_order(&self) -> ByteOrder {
48        self.order
49    }
50
51    pub fn has_space(&self, length: usize) -> UnityResult<usize> {
52        let end = length + self.get_offset();
53        if self.buf.len() < end {
54            Err(UnityError::Eof)
55        } else {
56            Ok(end)
57        }
58    }
59
60    pub fn align(&mut self, num: usize) -> UnityResult<usize> {
61        let offset_before_align = self.get_offset();
62        let remain = offset_before_align % num;
63        let offset_after_align = match remain {
64            0 => offset_before_align,
65            _ => offset_before_align - remain + num,
66        };
67        if offset_after_align > self.buf.len() {
68            return Err(UnityError::Eof);
69        }
70        self.set_offset(offset_after_align)?;
71        Ok(offset_after_align)
72    }
73
74    pub fn read_u8_slice(&mut self, length: usize) -> UnityResult<&[u8]> {
75        let end = self.has_space(length)?;
76        let result = &self.buf[self.offset..end];
77        self.offset = end;
78        Ok(result)
79    }
80
81    pub fn read_u8_array<const N: usize>(&mut self) -> UnityResult<[u8; N]> {
82        let mut result = [0; N];
83        let end = self.has_space(N)?;
84        let slice = &self.buf[self.get_offset()..end];
85        result.copy_from_slice(slice);
86        self.offset = end;
87        Ok(result)
88    }
89
90    pub fn read_f32_array<const N: usize>(&mut self) -> UnityResult<[f32; N]> {
91        let mut result = [0.0; N];
92        let end = self.has_space(N * std::mem::size_of::<f32>())?;
93        for i in 0..N {
94            result[i] = self.read_f32()?;
95        }
96        self.offset = end;
97        Ok(result)
98    }
99
100    pub fn read_i32_array<const N: usize>(&mut self) -> UnityResult<[i32; N]> {
101        let mut result = [0; N];
102        let end = self.has_space(N * std::mem::size_of::<i32>())?;
103        for i in 0..N {
104            result[i] = self.read_i32()?;
105        }
106        self.offset = end;
107        Ok(result)
108    }
109
110    pub fn read_u8_list(&mut self, length: usize) -> UnityResult<Vec<u8>> {
111        Ok(self.read_u8_slice(length)?.to_vec())
112    }
113
114    pub fn read_u8(&mut self) -> UnityResult<u8> {
115        let end = self.has_space(1)?;
116        let result = self.buf[self.offset];
117        self.offset = end;
118        Ok(result)
119    }
120
121    pub fn read_bool(&mut self) -> UnityResult<bool> {
122        Ok(self.read_u8()? != 0)
123    }
124
125    pub fn read_u16(&mut self) -> UnityResult<u16> {
126        let a = self.read_u8_array::<2>()?;
127        match self.order {
128            ByteOrder::Big => Ok(u16::from_be_bytes(a)),
129            ByteOrder::Little => Ok(u16::from_le_bytes(a)),
130        }
131    }
132
133    pub fn read_u32(&mut self) -> UnityResult<u32> {
134        let a = self.read_u8_array::<4>()?;
135        match self.order {
136            ByteOrder::Big => Ok(u32::from_be_bytes(a)),
137            ByteOrder::Little => Ok(u32::from_le_bytes(a)),
138        }
139    }
140
141    pub fn read_u64(&mut self) -> UnityResult<u64> {
142        let a = self.read_u8_array::<8>()?;
143        match self.order {
144            ByteOrder::Big => Ok(u64::from_be_bytes(a)),
145            ByteOrder::Little => Ok(u64::from_le_bytes(a)),
146        }
147    }
148
149    pub fn read_i8(&mut self) -> UnityResult<i8> {
150        let a = self.read_u8_array::<1>()?;
151        Ok(i8::from_be_bytes(a))
152    }
153
154    pub fn read_i16(&mut self) -> UnityResult<i16> {
155        let a = self.read_u8_array::<2>()?;
156        match self.order {
157            ByteOrder::Big => Ok(i16::from_be_bytes(a)),
158            ByteOrder::Little => Ok(i16::from_le_bytes(a)),
159        }
160    }
161
162    pub fn read_i32(&mut self) -> UnityResult<i32> {
163        let a = self.read_u8_array::<4>()?;
164        match self.order {
165            ByteOrder::Big => Ok(i32::from_be_bytes(a)),
166            ByteOrder::Little => Ok(i32::from_le_bytes(a)),
167        }
168    }
169
170    pub fn read_i64(&mut self) -> UnityResult<i64> {
171        let a = self.read_u8_array::<8>()?;
172        match self.order {
173            ByteOrder::Big => Ok(i64::from_be_bytes(a)),
174            ByteOrder::Little => Ok(i64::from_le_bytes(a)),
175        }
176    }
177
178    pub fn read_f32(&mut self) -> UnityResult<f32> {
179        let a = self.read_u8_array::<4>()?;
180        match self.order {
181            ByteOrder::Big => Ok(f32::from_be_bytes(a)),
182            ByteOrder::Little => Ok(f32::from_le_bytes(a)),
183        }
184    }
185
186    pub fn read_f64(&mut self) -> UnityResult<f64> {
187        let a = self.read_u8_array::<8>()?;
188        match self.order {
189            ByteOrder::Big => Ok(f64::from_be_bytes(a)),
190            ByteOrder::Little => Ok(f64::from_le_bytes(a)),
191        }
192    }
193
194    pub fn read_7bit_u32(&mut self) -> UnityResult<u32> {
195        let mut out = 0u32;
196        let mut shift = 0u32;
197        loop {
198            let b = self.read_u8()?;
199            out |= ((b & 0x7f) as u32) << shift;
200            shift += 7;
201            if b & 0x80 == 0 {
202                break;
203            }
204        }
205        Ok(out)
206    }
207
208    pub fn read_string_util_null(&mut self) -> UnityResult<String> {
209        let mut ret = String::new();
210        loop {
211            let b = self.read_u8()?;
212            if b == 0 {
213                break;
214            } else {
215                ret.push(b as char);
216            }
217        }
218        Ok(ret)
219    }
220
221    pub fn read_string_util_null_with_limit(&mut self, limit: usize) -> UnityResult<String> {
222        let mut ret = String::new();
223        for _ in 0..limit {
224            let b = self.read_u8()?;
225            if b == 0 {
226                break;
227            } else {
228                ret.push(b as char);
229            }
230        }
231        Ok(ret)
232    }
233
234    pub fn read_string_with_length(&mut self, length: usize) -> UnityResult<String> {
235        let mut ret = String::with_capacity(length);
236        for _ in 0..length {
237            let b = self.read_u8()?;
238            ret.push(b as char);
239        }
240        Ok(ret)
241    }
242
243    pub fn read_string_with_7bit_length(&mut self) -> UnityResult<String> {
244        let length = self.read_7bit_u32()?;
245        self.read_string_with_length(length as usize)
246    }
247
248    pub fn read_aligned_string(&mut self) -> UnityResult<String> {
249        let this = self as *mut Self;
250        let length = self.read_i32()?;
251        let result = self.read_string_with_length(length as usize);
252        unsafe {
253            this.as_mut().unwrap().align(4)?;
254        }
255        result
256    }
257
258    pub fn read_i32_list(&mut self, length: usize) -> UnityResult<Vec<i32>> {
259        self.has_space(length)?;
260        let mut ret = Vec::with_capacity(length);
261        for _ in 0..length {
262            ret.push(self.read_i32()?)
263        }
264        Ok(ret)
265    }
266
267    pub fn read_rect_f32(&mut self) -> UnityResult<RectF32> {
268        Ok(RectF32 { x: self.read_f32()?, y: self.read_f32()?, w: self.read_f32()?, h: self.read_f32()? })
269    }
270
271    pub fn read_vector2(&mut self) -> UnityResult<Vector2> {
272        Ok(Vector2 { x: self.read_f32()?, y: self.read_f32()? })
273    }
274
275    pub fn read_vector3(&mut self) -> UnityResult<Vector3> {
276        Ok(Vector3 { x: self.read_f32()?, y: self.read_f32()?, z: self.read_f32()? })
277    }
278
279    pub fn read_vector4(&mut self) -> UnityResult<Vector4> {
280        Ok(Vector4 { x: self.read_f32()?, y: self.read_f32()?, z: self.read_f32()?, w: self.read_f32()? })
281    }
282
283    pub fn read_matrix4x4(&mut self) -> UnityResult<Matrix4x4> {
284        Ok(Matrix4x4 { m00: self.read_f32()?, m10: self.read_f32()?, m20: self.read_f32()?, m30: self.read_f32()?, m01: self.read_f32()?, m11: self.read_f32()?, m21: self.read_f32()?, m31: self.read_f32()?, m02: self.read_f32()?, m12: self.read_f32()?, m22: self.read_f32()?, m32: self.read_f32()?, m03: self.read_f32()?, m13: self.read_f32()?, m23: self.read_f32()?, m33: self.read_f32()? })
285    }
286
287    pub fn read_u16_list(&mut self, size: usize) -> UnityResult<Vec<u16>> {
288        let _end = self.has_space(size)?;
289        let mut ret = Vec::with_capacity(size);
290        for _ in 0..size {
291            ret.push(self.read_u16()?)
292        }
293        Ok(ret)
294    }
295
296    pub fn read_string_list(&mut self) -> UnityResult<Vec<String>> {
297        let length = self.read_i32()?;
298        let mut result = Vec::with_capacity(length as usize);
299        for _ in 0..length {
300            result.push(self.read_aligned_string()?);
301        }
302        Ok(result)
303    }
304
305    pub fn read_f32_list(&mut self, size: usize) -> UnityResult<Vec<f32>> {
306        let _end = self.has_space(size)?;
307        let mut ret = Vec::with_capacity(size);
308        for _ in 0..size {
309            ret.push(self.read_f32()?)
310        }
311        Ok(ret)
312    }
313
314    pub fn read_matrix4x4_list(&mut self, size: usize) -> UnityResult<Vec<Matrix4x4>> {
315        let _end = self.has_space(size)?;
316        let mut ret = Vec::with_capacity(size);
317        for _ in 0..size {
318            ret.push(self.read_matrix4x4()?)
319        }
320        Ok(ret)
321    }
322}