use structure for timestamp information
[nihav.git] / src / io / byteio.rs
CommitLineData
90aa4e6b
KS
1use std::io::SeekFrom;
2use std::fs::File;
3use std::io::prelude::*;
4
5#[derive(Debug)]
6pub enum ByteIOError {
7 EOF,
8 WrongRange,
9 WrongIOMode,
10 NotImplemented,
11 ReadError,
12 WriteError,
13 SeekError,
14}
15
16type ByteIOResult<T> = Result<T, ByteIOError>;
17
18pub trait ByteIO {
19 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
89de616c 20 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
794364cf 21 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
90aa4e6b 22 fn read_byte(&mut self) -> ByteIOResult<u8>;
794364cf 23 fn peek_byte(&mut self) -> ByteIOResult<u8>;
90aa4e6b
KS
24 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<usize>;
25 fn tell(&mut self) -> u64;
26 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64>;
27 fn is_eof(&mut self) -> bool;
28 fn is_seekable(&mut self) -> bool;
29}
30
31#[allow(dead_code)]
32pub struct ByteReader<'a> {
33 io: &'a mut ByteIO,
34}
35
36pub struct MemoryReader<'a> {
37 buf: &'a [u8],
38 size: usize,
39 pos: usize,
90aa4e6b
KS
40}
41
42pub struct FileReader<'a> {
43 file: &'a File,
44 eof: bool,
45}
46
47macro_rules! read_int {
48 ($s: ident, $inttype: ty, $size: expr, $which: ident) => ({
49 let mut buf = [0; $size];
50 try!($s.read_buf(&mut buf));
51 unsafe {
52 Ok((*(buf.as_ptr() as *const $inttype)).$which())
53 }
54 })
55}
56
794364cf
KS
57macro_rules! peek_int {
58 ($s: ident, $inttype: ty, $size: expr, $which: ident) => ({
59 let mut buf = [0; $size];
60 try!($s.peek_buf(&mut buf));
61 unsafe {
62 Ok((*(buf.as_ptr() as *const $inttype)).$which())
63 }
64 })
65}
66
90aa4e6b 67impl<'a> ByteReader<'a> {
5a5a3ecb 68 pub fn new(io: &'a mut ByteIO) -> Self { ByteReader { io: io } }
90aa4e6b
KS
69
70 pub fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
71 self.io.read_buf(buf)
72 }
73
89de616c
KS
74 pub fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
75 self.io.read_buf_some(buf)
76 }
77
794364cf
KS
78 pub fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
79 self.io.peek_buf(buf)
80 }
81
90aa4e6b
KS
82 pub fn read_byte(&mut self) -> ByteIOResult<u8> {
83 self.io.read_byte()
84 }
85
794364cf
KS
86 pub fn peek_byte(&mut self) -> ByteIOResult<u8> {
87 self.io.peek_byte()
88 }
89
90aa4e6b
KS
90 pub fn read_u16be(&mut self) -> ByteIOResult<u16> {
91 read_int!(self, u16, 2, to_be)
92 }
93
794364cf
KS
94 pub fn peek_u16be(&mut self) -> ByteIOResult<u16> {
95 peek_int!(self, u16, 2, to_be)
96 }
97
90aa4e6b 98 pub fn read_u24be(&mut self) -> ByteIOResult<u32> {
794364cf
KS
99 let p16 = self.read_u16be()?;
100 let p8 = self.read_byte()?;
101 Ok(((p16 as u32) << 8) | (p8 as u32))
102 }
103
104 pub fn peek_u24be(&mut self) -> ByteIOResult<u32> {
105 let mut src: [u8; 3] = [0; 3];
106 self.peek_buf(&mut src)?;
107 Ok(((src[0] as u32) << 16) | ((src[1] as u32) << 8) | (src[2] as u32))
90aa4e6b
KS
108 }
109
110 pub fn read_u32be(&mut self) -> ByteIOResult<u32> {
111 read_int!(self, u32, 4, to_be)
112 }
113
794364cf
KS
114 pub fn peek_u32be(&mut self) -> ByteIOResult<u32> {
115 peek_int!(self, u32, 4, to_be)
116 }
117
90aa4e6b
KS
118 pub fn read_u64be(&mut self) -> ByteIOResult<u64> {
119 read_int!(self, u64, 8, to_be)
120 }
121
794364cf
KS
122 pub fn peek_u64be(&mut self) -> ByteIOResult<u64> {
123 peek_int!(self, u64, 8, to_be)
124 }
125
90aa4e6b
KS
126 pub fn read_u16le(&mut self) -> ByteIOResult<u16> {
127 read_int!(self, u16, 2, to_le)
128 }
129
794364cf
KS
130 pub fn peek_u16le(&mut self) -> ByteIOResult<u16> {
131 peek_int!(self, u16, 2, to_le)
132 }
133
90aa4e6b 134 pub fn read_u24le(&mut self) -> ByteIOResult<u32> {
794364cf
KS
135 let p8 = self.read_byte()?;
136 let p16 = self.read_u16le()?;
137 Ok(((p16 as u32) << 8) | (p8 as u32))
138 }
139
140 pub fn peek_u24le(&mut self) -> ByteIOResult<u32> {
141 let mut src: [u8; 3] = [0; 3];
142 self.peek_buf(&mut src)?;
143 Ok((src[0] as u32) | ((src[1] as u32) << 8) | ((src[2] as u32) << 16))
90aa4e6b
KS
144 }
145
146 pub fn read_u32le(&mut self) -> ByteIOResult<u32> {
147 read_int!(self, u32, 4, to_le)
148 }
149
794364cf
KS
150 pub fn peek_u32le(&mut self) -> ByteIOResult<u32> {
151 peek_int!(self, u32, 4, to_le)
152 }
153
90aa4e6b
KS
154 pub fn read_u64le(&mut self) -> ByteIOResult<u64> {
155 read_int!(self, u64, 8, to_le)
156 }
157
794364cf
KS
158 pub fn peek_u64le(&mut self) -> ByteIOResult<u64> {
159 peek_int!(self, u64, 8, to_le)
160 }
161
6b167b0c 162 pub fn read_skip(&mut self, len: usize) -> ByteIOResult<()> {
90aa4e6b
KS
163 if self.io.is_seekable() {
164 self.io.seek(SeekFrom::Current(len as i64))?;
165 } else {
166 let mut ssize = len;
167 let mut buf : [u8; 16] = [0; 16];
168 let mut bref = &mut buf;
169 while ssize > bref.len() {
170 self.io.read_buf(bref)?;
171 ssize -= bref.len();
172 }
173 while ssize > 0 {
174 self.io.read_byte()?;
175 ssize = ssize - 1;
176 }
177 }
6b167b0c 178 Ok(())
90aa4e6b
KS
179 }
180
181 pub fn tell(&mut self) -> u64 {
182 self.io.tell()
183 }
184
185 pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
186 self.io.seek(pos)
187 }
188
189 pub fn is_eof(&mut self) -> bool {
190 self.io.is_eof()
191 }
192}
193
194impl<'a> MemoryReader<'a> {
195
196 pub fn new_read(buf: &'a [u8]) -> Self {
794364cf 197 MemoryReader { buf: buf, size: buf.len(), pos: 0 }
90aa4e6b
KS
198 }
199
200 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
201 if pos < 0 || (pos as usize) > self.size {
202 return Err(ByteIOError::WrongRange)
203 }
204 self.pos = pos as usize;
205 Ok(pos as u64)
206 }
90aa4e6b
KS
207}
208
209impl<'a> ByteIO for MemoryReader<'a> {
210 fn read_byte(&mut self) -> ByteIOResult<u8> {
90aa4e6b
KS
211 if self.is_eof() { return Err(ByteIOError::EOF); }
212 let res = self.buf[self.pos];
213 self.pos = self.pos + 1;
214 Ok(res)
215 }
216
794364cf
KS
217 fn peek_byte(&mut self) -> ByteIOResult<u8> {
218 if self.is_eof() { return Err(ByteIOError::EOF); }
219 Ok(self.buf[self.pos])
220 }
221
222 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
90aa4e6b
KS
223 let copy_size = if self.size - self.pos < buf.len() { self.size } else { buf.len() };
224 if copy_size == 0 { return Err(ByteIOError::EOF); }
225 for i in 0..copy_size {
226 buf[i] = self.buf[self.pos + i];
227 }
90aa4e6b
KS
228 Ok(copy_size)
229 }
230
794364cf 231 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
89de616c
KS
232 let read_size = self.peek_buf(buf)?;
233 if read_size < buf.len() { return Err(ByteIOError::EOF); }
234 self.pos += read_size;
235 Ok(read_size)
236 }
237
238 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
794364cf
KS
239 let read_size = self.peek_buf(buf)?;
240 self.pos += read_size;
241 Ok(read_size)
242 }
243
90aa4e6b
KS
244 #[allow(unused_variables)]
245 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<usize> {
90aa4e6b
KS
246 Err(ByteIOError::NotImplemented)
247 }
248
249 fn tell(&mut self) -> u64 {
250 self.pos as u64
251 }
252
253 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
254 let cur_pos = self.pos as i64;
255 let cur_size = self.size as i64;
256 match pos {
257 SeekFrom::Start(x) => self.real_seek(x as i64),
258 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
259 SeekFrom::End(x) => self.real_seek(cur_size + x),
260 }
261 }
262
263 fn is_eof(&mut self) -> bool {
264 self.pos >= self.size
265 }
266
267 fn is_seekable(&mut self) -> bool {
268 true
269 }
270}
271
272impl<'a> FileReader<'a> {
273
274 pub fn new_read(file: &'a mut File) -> Self {
275 FileReader { file: file, eof : false }
276 }
277}
278
279impl<'a> ByteIO for FileReader<'a> {
280 fn read_byte(&mut self) -> ByteIOResult<u8> {
281 let mut byte : [u8; 1] = [0];
282 let err = self.file.read(&mut byte);
283 if let Err(_) = err { return Err(ByteIOError::ReadError); }
284 let sz = err.unwrap();
285 if sz == 0 { self.eof = true; return Err(ByteIOError::EOF); }
286 Ok (byte[0])
287 }
288
794364cf
KS
289 fn peek_byte(&mut self) -> ByteIOResult<u8> {
290 let b = self.read_byte()?;
291 self.seek(SeekFrom::Current(-1))?;
292 Ok(b)
293 }
294
90aa4e6b
KS
295 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
296 let res = self.file.read(buf);
297 if let Err(_) = res { return Err(ByteIOError::ReadError); }
89de616c
KS
298 let sz = res.unwrap();
299 if sz < buf.len() { self.eof = true; return Err(ByteIOError::EOF); }
300 Ok(sz)
301 }
302
303 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
304 let res = self.file.read(buf);
305 if let Err(_) = res { return Err(ByteIOError::ReadError); }
90aa4e6b
KS
306 let sz = res.unwrap();
307 if sz < buf.len() { self.eof = true; }
308 Ok(sz)
309 }
310
794364cf
KS
311 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
312 let size = self.read_buf(buf)?;
313 self.seek(SeekFrom::Current(-(size as i64)))?;
314 Ok(size)
315 }
316
90aa4e6b
KS
317 #[allow(unused_variables)]
318 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<usize> {
319 Err(ByteIOError::NotImplemented)
320 }
321
322 fn tell(&mut self) -> u64 {
323 self.file.seek(SeekFrom::Current(0)).unwrap()
324 }
325
326 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
327 let res = self.file.seek(pos);
328 match res {
329 Ok(r) => Ok(r),
330 Err(_) => Err(ByteIOError::SeekError),
331 }
332 }
333
334 fn is_eof(&mut self) -> bool {
335 self.eof
336 }
337
338 fn is_seekable(&mut self) -> bool {
339 true
340 }
341}
342
343#[cfg(test)]
344mod test {
345 use super::*;
346 use std::fs::File;
347
348 #[test]
349 fn test_read() {
350 //const DATA : &'static [u8] = include_bytes!("../../assets/file");
351 let buf: [u8; 64] = [1; 64];
352 let mut mr = MemoryReader::new_read(&buf);
353 let mut reader = ByteReader::new(&mut mr);
354 assert_eq!(reader.read_byte().unwrap(), 0x01u8);
355 assert_eq!(reader.read_u16le().unwrap(), 0x0101u16);
356 assert_eq!(reader.read_u24le().unwrap(), 0x010101u32);
357 assert_eq!(reader.read_u32le().unwrap(), 0x01010101u32);
358 assert_eq!(reader.read_u64le().unwrap(), 0x0101010101010101u64);
359 let mut file = File::open("assets/MaoMacha.asx").unwrap();
360 let mut fr = FileReader::new_read(&mut file);
361 let mut br2 = ByteReader::new(&mut fr);
362 assert_eq!(br2.read_byte().unwrap(), 0x30);
363 assert_eq!(br2.read_u24be().unwrap(), 0x26B275);
364 assert_eq!(br2.read_u24le().unwrap(), 0xCF668E);
365 assert_eq!(br2.read_u32be().unwrap(), 0x11A6D900);
366 assert_eq!(br2.read_u32le().unwrap(), 0xCE6200AA);
367 }
368 #[test]
369 fn test_write() {
370 }
371}