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