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}