gistools/parsers/read/
file.rs

1use super::StdReader;
2use crate::parsers::Reader;
3use core::cell::RefCell;
4use half::f16;
5use std::{
6    fs::File,
7    io::{self, Read, Seek, SeekFrom},
8    path::{Path, PathBuf},
9    string::{String, ToString},
10    vec,
11    vec::Vec,
12};
13
14/// A file reader for reading data from a file
15///
16/// Implements the [`Reader`] trait.
17#[derive(Debug)]
18pub struct FileReader {
19    path: PathBuf,
20    file: RefCell<File>,
21    size: u64,
22    cursor: RefCell<u64>,
23}
24
25impl FileReader {
26    /// Creates a new file reader from a file path
27    pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
28        let path_buf = path.as_ref().to_path_buf();
29        let file = File::open(path)?;
30        let size = file.metadata().map(|metadata| metadata.len()).unwrap_or(0);
31        Ok(Self { path: path_buf, file: file.into(), size, cursor: 0.into() })
32    }
33
34    fn seek_to(&self, offset: u64) {
35        if *self.cursor.borrow() != offset {
36            self.file.borrow_mut().seek(SeekFrom::Start(offset)).expect("Failed to seek");
37            *self.cursor.borrow_mut() = offset;
38        }
39    }
40
41    fn get_bytes(&self, byte_offset: Option<u64>, byte_length: u64) -> Vec<u8> {
42        let offset = byte_offset.unwrap_or(*self.cursor.borrow());
43        assert!(offset + byte_length <= self.size);
44        self.seek_to(offset);
45
46        let mut buffer = vec![0u8; byte_length as usize];
47        self.file.borrow_mut().read_exact(&mut buffer).expect("Failed to read bytes");
48        *self.cursor.borrow_mut() = offset + byte_length;
49
50        buffer
51    }
52}
53impl StdReader for FileReader {
54    fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
55        let path_buf = path.as_ref().to_path_buf();
56        let file = File::open(path)?;
57        let size = file.metadata().map(|metadata| metadata.len()).unwrap_or(0);
58        Ok(Self { path: path_buf, file: file.into(), size, cursor: 0.into() })
59    }
60}
61impl Clone for FileReader {
62    fn clone(&self) -> Self {
63        FileReader::new(&self.path).unwrap()
64    }
65}
66impl Reader for FileReader {
67    fn len(&self) -> u64 {
68        self.size
69    }
70
71    // GETTERS
72
73    fn uint64(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> u64 {
74        if little_endian.unwrap_or(false) {
75            self.uint64_le(byte_offset)
76        } else {
77            self.uint64_be(byte_offset)
78        }
79    }
80    fn uint64_be(&self, byte_offset: Option<u64>) -> u64 {
81        let bytes = self.get_bytes(byte_offset, 8);
82        u64::from_be_bytes(bytes.try_into().expect("Failed to read 8 bytes"))
83    }
84    fn uint64_le(&self, byte_offset: Option<u64>) -> u64 {
85        let bytes = self.get_bytes(byte_offset, 8);
86        u64::from_le_bytes(bytes.try_into().expect("Failed to read 8 bytes"))
87    }
88
89    fn int64(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> i64 {
90        if little_endian.unwrap_or(false) {
91            self.int64_le(byte_offset)
92        } else {
93            self.int64_be(byte_offset)
94        }
95    }
96    fn int64_be(&self, byte_offset: Option<u64>) -> i64 {
97        let bytes = self.get_bytes(byte_offset, 8);
98        i64::from_be_bytes(bytes.try_into().expect("Failed to read 8 bytes"))
99    }
100    fn int64_le(&self, byte_offset: Option<u64>) -> i64 {
101        let bytes = self.get_bytes(byte_offset, 8);
102        i64::from_le_bytes(bytes.try_into().expect("Failed to read 8 bytes"))
103    }
104
105    fn f64(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> f64 {
106        if little_endian.unwrap_or(false) {
107            self.f64_le(byte_offset)
108        } else {
109            self.f64_be(byte_offset)
110        }
111    }
112    fn f64_be(&self, byte_offset: Option<u64>) -> f64 {
113        let bytes = self.get_bytes(byte_offset, 8);
114        f64::from_be_bytes(bytes.try_into().expect("Failed to read 8 bytes"))
115    }
116    fn f64_le(&self, byte_offset: Option<u64>) -> f64 {
117        let bytes = self.get_bytes(byte_offset, 8);
118        f64::from_le_bytes(bytes.try_into().expect("Failed to read 8 bytes"))
119    }
120
121    fn uint32(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> u32 {
122        if little_endian.unwrap_or(false) {
123            self.uint32_le(byte_offset)
124        } else {
125            self.uint32_be(byte_offset)
126        }
127    }
128    fn uint32_be(&self, byte_offset: Option<u64>) -> u32 {
129        let bytes = self.get_bytes(byte_offset, 4);
130        u32::from_be_bytes(bytes.try_into().expect("Failed to read 4 bytes"))
131    }
132    fn uint32_le(&self, byte_offset: Option<u64>) -> u32 {
133        let bytes = self.get_bytes(byte_offset, 4);
134        u32::from_le_bytes(bytes.try_into().expect("Failed to read 4 bytes"))
135    }
136
137    fn int32(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> i32 {
138        if little_endian.unwrap_or(false) {
139            self.int32_le(byte_offset)
140        } else {
141            self.int32_be(byte_offset)
142        }
143    }
144    fn int32_be(&self, byte_offset: Option<u64>) -> i32 {
145        let bytes = self.get_bytes(byte_offset, 4);
146        i32::from_be_bytes(bytes.try_into().expect("Failed to read 4 bytes"))
147    }
148    fn int32_le(&self, byte_offset: Option<u64>) -> i32 {
149        let bytes = self.get_bytes(byte_offset, 4);
150        i32::from_le_bytes(bytes.try_into().expect("Failed to read 4 bytes"))
151    }
152
153    fn f32(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> f32 {
154        if little_endian.unwrap_or(false) {
155            self.f32_le(byte_offset)
156        } else {
157            self.f32_be(byte_offset)
158        }
159    }
160    fn f32_be(&self, byte_offset: Option<u64>) -> f32 {
161        let bytes = self.get_bytes(byte_offset, 4);
162        f32::from_be_bytes(bytes.try_into().expect("Failed to read 4 bytes"))
163    }
164    fn f32_le(&self, byte_offset: Option<u64>) -> f32 {
165        let bytes = self.get_bytes(byte_offset, 4);
166        f32::from_le_bytes(bytes.try_into().expect("Failed to read 4 bytes"))
167    }
168
169    fn uint16(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> u16 {
170        if little_endian.unwrap_or(false) {
171            self.uint16_le(byte_offset)
172        } else {
173            self.uint16_be(byte_offset)
174        }
175    }
176    fn uint16_be(&self, byte_offset: Option<u64>) -> u16 {
177        let bytes = self.get_bytes(byte_offset, 2);
178        u16::from_be_bytes(bytes.try_into().expect("Failed to read 2 bytes"))
179    }
180    fn uint16_le(&self, byte_offset: Option<u64>) -> u16 {
181        let bytes = self.get_bytes(byte_offset, 2);
182        u16::from_le_bytes(bytes.try_into().expect("Failed to read 2 bytes"))
183    }
184
185    fn int16(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> i16 {
186        if little_endian.unwrap_or(false) {
187            self.int16_le(byte_offset)
188        } else {
189            self.int16_be(byte_offset)
190        }
191    }
192    fn int16_be(&self, byte_offset: Option<u64>) -> i16 {
193        let bytes = self.get_bytes(byte_offset, 2);
194        i16::from_be_bytes(bytes.try_into().expect("Failed to read 2 bytes"))
195    }
196    fn int16_le(&self, byte_offset: Option<u64>) -> i16 {
197        let bytes = self.get_bytes(byte_offset, 2);
198        i16::from_le_bytes(bytes.try_into().expect("Failed to read 2 bytes"))
199    }
200
201    fn f16(&self, byte_offset: Option<u64>, little_endian: Option<bool>) -> f32 {
202        if little_endian.unwrap_or(false) {
203            self.f16_le(byte_offset)
204        } else {
205            self.f16_be(byte_offset)
206        }
207    }
208    fn f16_be(&self, byte_offset: Option<u64>) -> f32 {
209        let bytes = self.get_bytes(byte_offset, 2);
210        let f = f16::from_be_bytes(bytes.try_into().expect("Failed to read 2 bytes"));
211        f32::from_bits(f.to_bits().into())
212    }
213    fn f16_le(&self, byte_offset: Option<u64>) -> f32 {
214        let bytes = self.get_bytes(byte_offset, 2);
215        let f = f16::from_le_bytes(bytes.try_into().expect("Failed to read 2 bytes"));
216        f32::from_bits(f.to_bits().into())
217    }
218
219    fn uint8(&self, byte_offset: Option<u64>) -> u8 {
220        let bytes = self.get_bytes(byte_offset, 1);
221        bytes[0]
222    }
223    fn int8(&self, byte_offset: Option<u64>) -> i8 {
224        let bytes = self.get_bytes(byte_offset, 1);
225        bytes[0] as i8
226    }
227
228    // Methods
229
230    fn tell(&self) -> u64 {
231        *self.cursor.borrow()
232    }
233
234    fn seek(&self, pos: u64) {
235        self.seek_to(pos);
236    }
237
238    fn slice(&self, begin: Option<u64>, end: Option<u64>) -> Vec<u8> {
239        let cursor = *self.cursor.borrow();
240        let start = begin.unwrap_or(cursor);
241        let end = end.unwrap_or(cursor);
242        self.get_bytes(Some(start), end - start)
243    }
244
245    fn seek_slice(&self, size: usize) -> Vec<u8> {
246        let mut buffer = vec![0u8; size];
247        self.file.borrow_mut().read_exact(&mut buffer).expect("Failed to read slice");
248        *self.cursor.borrow_mut() += size as u64;
249        buffer
250    }
251
252    fn parse_string(&self, byte_offset: Option<u64>, byte_length: Option<u64>) -> String {
253        let offset = byte_offset.unwrap_or(*self.cursor.borrow());
254        let length = byte_length.unwrap_or(self.size - offset);
255        let bytes = self.get_bytes(Some(offset), length);
256        // Remove null bytes from the byte slice before decoding it
257        let cleaned_str_buf: Vec<u8> = bytes.iter().cloned().filter(|&b| b != 0).collect();
258        let string = String::from_utf8_lossy(&cleaned_str_buf).to_string();
259        *self.cursor.borrow_mut() = offset + length;
260        string
261    }
262}
263impl From<PathBuf> for FileReader {
264    fn from(path: PathBuf) -> Self {
265        FileReader::new(path).unwrap()
266    }
267}
268impl From<String> for FileReader {
269    fn from(path: String) -> Self {
270        FileReader::new(path).unwrap()
271    }
272}
273impl From<&str> for FileReader {
274    fn from(path: &str) -> Self {
275        FileReader::new(path).unwrap()
276    }
277}