core/byteio: add read_tag/peek_tag for reading four-byte tags
[nihav.git] / nihav-core / src / io / byteio.rs
1 //! Bytestream reading/writing functionality.
2 pub use std::io::SeekFrom;
3 use std::fs::File;
4 use std::io::prelude::*;
5 use std::ptr;
6
7 /// A list specifying general bytestream reading and writing errors.
8 #[derive(Debug)]
9 pub enum ByteIOError {
10 /// End of stream.
11 EOF,
12 /// Wrong seek position was provided.
13 WrongRange,
14 /// Tried to call read() on bytestream writer or write() on bytestream reader.
15 WrongIOMode,
16 /// Functionality is not implemented.
17 NotImplemented,
18 /// Read error.
19 ReadError,
20 /// Write error.
21 WriteError,
22 /// Seeking failed.
23 SeekError,
24 }
25
26 /// A specialised `Result` type for bytestream operations.
27 pub type ByteIOResult<T> = Result<T, ByteIOError>;
28
29 /// Common trait for bytestream operations.
30 pub trait ByteIO {
31 /// Reads data into provided buffer. Fails if it cannot fill whole buffer.
32 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
33 /// Reads data into provided buffer. Partial read is treated as success.
34 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
35 /// Reads data into provided buffer but does not advance read position.
36 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
37 /// Reads single byte from the stream.
38 fn read_byte(&mut self) -> ByteIOResult<u8>;
39 /// Returns the next byte value in the stream without advancing read position.
40 fn peek_byte(&mut self) -> ByteIOResult<u8>;
41 /// Writes buffer to the stream.
42 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()>;
43 /// Returns current read or write position.
44 fn tell(&mut self) -> u64;
45 /// Seeks to the provided position.
46 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64>;
47 /// Tells whether this is end of stream.
48 fn is_eof(&self) -> bool;
49 /// Reports whether stream is seekable or not.
50 fn is_seekable(&mut self) -> bool;
51 /// Returns stream size or -1 if it is not known.
52 fn size(&mut self) -> i64;
53 }
54
55 /// High-level bytestream reader.
56 ///
57 /// User is supposed to create some reader implementing [`ByteIO`] trait e.g. [`MemoryReader`] and use it to create `ByteReader` which can be used for reading e.g. various integer types.
58 ///
59 /// # Examples
60 ///
61 /// ````
62 /// use nihav_core::io::byteio::{MemoryReader,ByteReader};
63 /// # use nihav_core::io::byteio::ByteIOResult;
64 ///
65 /// # fn foo() -> ByteIOResult<()> {
66 /// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
67 /// let mut mr = MemoryReader::new_read(&memory);
68 /// let mut br = ByteReader::new(&mut mr);
69 /// let val = br.read_u16be()?; // read 16-bit big-endian integer, should be 42
70 /// let val = br.read_u16le()?; // read 16-bit little-endian integer, should be 42 as well
71 /// # Ok(())
72 /// # }
73 /// ````
74 ///
75 /// [`ByteIO`]: ./trait.ByteIO.html
76 /// [`MemoryReader`]: ./struct.MemoryReader.html
77 #[allow(dead_code)]
78 pub struct ByteReader<'a> {
79 io: &'a mut ByteIO,
80 }
81
82 /// Bytestream reader from memory.
83 pub struct MemoryReader<'a> {
84 buf: &'a [u8],
85 pos: usize,
86 }
87
88 /// Bytestream reader from file.
89 pub struct FileReader<'a> {
90 file: &'a File,
91 eof: bool,
92 }
93
94 macro_rules! read_int {
95 ($s: ident, $inttype: ty, $size: expr, $which: ident) => ({
96 unsafe {
97 let mut buf: $inttype = 0;
98 $s.read_buf(&mut *(&mut buf as *mut $inttype as *mut [u8; $size]))?;
99 Ok(buf.$which())
100 }
101 })
102 }
103
104 macro_rules! peek_int {
105 ($s: ident, $inttype: ty, $size: expr, $which: ident) => ({
106 unsafe {
107 let mut buf: $inttype = 0;
108 $s.peek_buf(&mut *(&mut buf as *mut $inttype as *mut [u8; $size]))?;
109 Ok(buf.$which())
110 }
111 })
112 }
113
114 macro_rules! read_int_func {
115 ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
116 /// Reads integer of certain size and endianness.
117 pub fn $s(src: &[u8]) -> ByteIOResult<$inttype> {
118 if src.len() < $size { return Err(ByteIOError::ReadError); }
119 unsafe {
120 let mut buf: $inttype = 0;
121 ptr::copy_nonoverlapping(src.as_ptr(), &mut buf as *mut $inttype as *mut u8, std::mem::size_of::<$inttype>());
122 Ok(buf.$which())
123 }
124 }
125 }
126 }
127
128 read_int_func!(read_u16be, u16, 2, to_be);
129 read_int_func!(read_u16le, u16, 2, to_le);
130 read_int_func!(read_u32be, u32, 4, to_be);
131 read_int_func!(read_u32le, u32, 4, to_le);
132 read_int_func!(read_u64be, u64, 8, to_be);
133 read_int_func!(read_u64le, u64, 8, to_le);
134
135 /// Reads 24-bit big-endian integer.
136 ///
137 /// # Example
138 ///
139 /// ````
140 /// use nihav_core::io::byteio::read_u24be;
141 /// # use nihav_core::io::byteio::ByteIOResult;
142 ///
143 /// # fn foo() -> ByteIOResult<()> {
144 /// let src: [u8; 3] = [ 1, 2, 3];
145 /// let value = read_u24be(&src)?; // should return 0x010203
146 /// # Ok(())
147 /// # }
148 /// ````
149 pub fn read_u24be(src: &[u8]) -> ByteIOResult<u32> {
150 if src.len() < 3 { return Err(ByteIOError::ReadError); }
151 Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
152 }
153 /// Reads 24-bit little-endian integer.
154 pub fn read_u24le(src: &[u8]) -> ByteIOResult<u32> {
155 if src.len() < 3 { return Err(ByteIOError::ReadError); }
156 Ok((u32::from(src[2]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[0]))
157 }
158 /// Reads 32-bit big-endian floating point number.
159 pub fn read_f32be(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32be(src)?)) }
160 /// Reads 32-bit little-endian floating point number.
161 pub fn read_f32le(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32le(src)?)) }
162 /// Reads 64-bit big-endian floating point number.
163 pub fn read_f64be(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64be(src)?)) }
164 /// Reads 64-bit little-endian floating point number.
165 pub fn read_f64le(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64le(src)?)) }
166
167 macro_rules! write_int_func {
168 ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
169 /// Writes integer of certain size and endianness into byte buffer.
170 pub fn $s(dst: &mut [u8], val: $inttype) -> ByteIOResult<()> {
171 if dst.len() < $size { return Err(ByteIOError::WriteError); }
172 unsafe {
173 let val = val.$which();
174 ptr::copy_nonoverlapping(&val as *const $inttype as *const u8, dst.as_mut_ptr(), std::mem::size_of::<$inttype>());
175 }
176 Ok(())
177 }
178 }
179 }
180
181 write_int_func!(write_u16be, u16, 2, to_be);
182 write_int_func!(write_u16le, u16, 2, to_le);
183 write_int_func!(write_u32be, u32, 4, to_be);
184 write_int_func!(write_u32le, u32, 4, to_le);
185 write_int_func!(write_u64be, u64, 8, to_be);
186 write_int_func!(write_u64le, u64, 8, to_le);
187
188 /// Writes 24-bit big-endian integer to the provided buffer.
189 ///
190 /// # Example
191 ///
192 /// ````
193 /// use nihav_core::io::byteio::write_u24be;
194 /// # use nihav_core::io::byteio::ByteIOResult;
195 ///
196 /// # fn foo() -> ByteIOResult<()> {
197 /// let mut dst = [0u8; 3];
198 /// write_u24be(&mut dst, 0x010203)?;
199 /// // dst should contain [ 1, 2, 3] now
200 /// # Ok(())
201 /// # }
202 /// ````
203 pub fn write_u24be(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
204 if dst.len() < 3 { return Err(ByteIOError::WriteError); }
205 dst[0] = (val >> 16) as u8;
206 dst[1] = (val >> 8) as u8;
207 dst[2] = (val >> 0) as u8;
208 Ok(())
209 }
210 /// Writes 24-bit little-endian integer to the provided buffer.
211 pub fn write_u24le(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
212 if dst.len() < 3 { return Err(ByteIOError::WriteError); }
213 dst[0] = (val >> 0) as u8;
214 dst[1] = (val >> 8) as u8;
215 dst[2] = (val >> 16) as u8;
216 Ok(())
217 }
218 /// Writes 32-bit big-endian floating point number to the provided buffer.
219 pub fn write_f32be(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32be(dst, val.to_bits()) }
220 /// Writes 32-bit little-endian floating point number to the provided buffer.
221 pub fn write_f32le(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32le(dst, val.to_bits()) }
222 /// Writes 64-bit big-endian floating point number to the provided buffer.
223 pub fn write_f64be(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64be(dst, val.to_bits()) }
224 /// Writes 64-bit little-endian floating point number to the provided buffer.
225 pub fn write_f64le(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64le(dst, val.to_bits()) }
226
227 impl<'a> ByteReader<'a> {
228 /// Constructs a new instance of bytestream reader.
229 ///
230 /// # Examples
231 ///
232 /// ````
233 /// use nihav_core::io::byteio::{MemoryReader,ByteReader};
234 /// # use nihav_core::io::byteio::ByteIOResult;
235 ///
236 /// # fn foo() -> ByteIOResult<()> {
237 /// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
238 /// let mut mr = MemoryReader::new_read(&memory);
239 /// let mut br = ByteReader::new(&mut mr);
240 /// # Ok(())
241 /// # }
242 /// ````
243 pub fn new(io: &'a mut ByteIO) -> Self { ByteReader { io } }
244
245 /// Reads data into provided buffer. Partial read is treated as success.
246 pub fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
247 self.io.read_buf(buf)
248 }
249
250 /// Reads data into provided buffer. Partial read is treated as success.
251 pub fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
252 self.io.read_buf_some(buf)
253 }
254
255 /// Reads data into provided buffer but does not advance read position.
256 pub fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
257 self.io.peek_buf(buf)
258 }
259
260 /// Reads single byte from the stream.
261 pub fn read_byte(&mut self) -> ByteIOResult<u8> {
262 self.io.read_byte()
263 }
264
265 /// Returns the next byte value in the stream without advancing read position.
266 pub fn peek_byte(&mut self) -> ByteIOResult<u8> {
267 self.io.peek_byte()
268 }
269
270 /// Reads four-byte array from the stream.
271 pub fn read_tag(&mut self) -> ByteIOResult<[u8; 4]> {
272 let mut buf = [0u8; 4];
273 self.io.read_buf(&mut buf)?;
274 Ok(buf)
275 }
276
277 /// Reads four-byte array from the stream without advancing read position.
278 pub fn peek_tag(&mut self) -> ByteIOResult<[u8; 4]> {
279 let mut buf = [0u8; 4];
280 self.io.peek_buf(&mut buf)?;
281 Ok(buf)
282 }
283
284 /// Reads 16-bit big-endian integer from the stream.
285 pub fn read_u16be(&mut self) -> ByteIOResult<u16> {
286 read_int!(self, u16, 2, to_be)
287 }
288
289 /// Reads 16-bit big-endian integer from the stream without advancing read position.
290 pub fn peek_u16be(&mut self) -> ByteIOResult<u16> {
291 peek_int!(self, u16, 2, to_be)
292 }
293
294 /// Reads 24-bit big-endian integer from the stream.
295 pub fn read_u24be(&mut self) -> ByteIOResult<u32> {
296 let p16 = self.read_u16be()?;
297 let p8 = self.read_byte()?;
298 Ok((u32::from(p16) << 8) | u32::from(p8))
299 }
300
301 /// Reads 24-bit big-endian integer from the stream without advancing read position.
302 pub fn peek_u24be(&mut self) -> ByteIOResult<u32> {
303 let mut src: [u8; 3] = [0; 3];
304 self.peek_buf(&mut src)?;
305 Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
306 }
307
308 /// Reads 32-bit big-endian integer from the stream.
309 pub fn read_u32be(&mut self) -> ByteIOResult<u32> {
310 read_int!(self, u32, 4, to_be)
311 }
312
313 /// Reads 32-bit big-endian integer from the stream without advancing read position.
314 pub fn peek_u32be(&mut self) -> ByteIOResult<u32> {
315 peek_int!(self, u32, 4, to_be)
316 }
317
318 /// Reads 64-bit big-endian integer from the stream.
319 pub fn read_u64be(&mut self) -> ByteIOResult<u64> {
320 read_int!(self, u64, 8, to_be)
321 }
322
323 /// Reads 64-bit big-endian integer from the stream without advancing read position.
324 pub fn peek_u64be(&mut self) -> ByteIOResult<u64> {
325 peek_int!(self, u64, 8, to_be)
326 }
327
328 /// Reads 32-bit big-endian floating point number from the stream.
329 pub fn read_f32be(&mut self) -> ByteIOResult<f32> {
330 Ok(f32::from_bits(self.read_u32be()?))
331 }
332
333 /// Reads 32-bit big-endian floating point number from the stream without advancing read position.
334 pub fn peek_f32be(&mut self) -> ByteIOResult<f32> {
335 Ok(f32::from_bits(self.peek_u32be()?))
336 }
337
338 /// Reads 64-bit big-endian floating point number from the stream.
339 pub fn read_f64be(&mut self) -> ByteIOResult<f64> {
340 Ok(f64::from_bits(self.read_u64be()?))
341 }
342
343 /// Reads 64-bit big-endian floating point number from the stream without advancing read position.
344 pub fn peek_f64be(&mut self) -> ByteIOResult<f64> {
345 Ok(f64::from_bits(self.peek_u64be()?))
346 }
347
348 /// Reads 16-bit little-endian integer from the stream.
349 pub fn read_u16le(&mut self) -> ByteIOResult<u16> {
350 read_int!(self, u16, 2, to_le)
351 }
352
353 /// Reads 16-bit little-endian integer from the stream without advancing read position.
354 pub fn peek_u16le(&mut self) -> ByteIOResult<u16> {
355 peek_int!(self, u16, 2, to_le)
356 }
357
358 /// Reads 24-bit little-endian integer from the stream.
359 pub fn read_u24le(&mut self) -> ByteIOResult<u32> {
360 let p8 = self.read_byte()?;
361 let p16 = self.read_u16le()?;
362 Ok((u32::from(p16) << 8) | u32::from(p8))
363 }
364
365 /// Reads 24-bit little-endian integer from the stream without advancing read position.
366 pub fn peek_u24le(&mut self) -> ByteIOResult<u32> {
367 let mut src: [u8; 3] = [0; 3];
368 self.peek_buf(&mut src)?;
369 Ok(u32::from(src[0]) | (u32::from(src[1]) << 8) | (u32::from(src[2]) << 16))
370 }
371
372 /// Reads 32-bit little-endian integer from the stream.
373 pub fn read_u32le(&mut self) -> ByteIOResult<u32> {
374 read_int!(self, u32, 4, to_le)
375 }
376
377 /// Reads 32-bit little-endian integer from the stream without advancing read position.
378 pub fn peek_u32le(&mut self) -> ByteIOResult<u32> {
379 peek_int!(self, u32, 4, to_le)
380 }
381
382 /// Reads 64-bit little-endian integer from the stream.
383 pub fn read_u64le(&mut self) -> ByteIOResult<u64> {
384 read_int!(self, u64, 8, to_le)
385 }
386
387 /// Reads 64-bit little-endian integer from the stream without advancing read position.
388 pub fn peek_u64le(&mut self) -> ByteIOResult<u64> {
389 peek_int!(self, u64, 8, to_le)
390 }
391
392 /// Reads 32-bit little-endian floating point number from the stream.
393 pub fn read_f32le(&mut self) -> ByteIOResult<f32> {
394 Ok(f32::from_bits(self.read_u32le()?))
395 }
396
397 /// Reads 32-bit little-endian floating point number from the stream without advancing read position.
398 pub fn peek_f32le(&mut self) -> ByteIOResult<f32> {
399 Ok(f32::from_bits(self.peek_u32le()?))
400 }
401
402 /// Reads 64-bit little-endian floating point number from the stream.
403 pub fn read_f64le(&mut self) -> ByteIOResult<f64> {
404 Ok(f64::from_bits(self.read_u64le()?))
405 }
406
407 /// Reads 64-bit little-endian floating point number from the stream without advancing read position.
408 pub fn peek_f64le(&mut self) -> ByteIOResult<f64> {
409 Ok(f64::from_bits(self.peek_u64le()?))
410 }
411
412 /// Skips requested number of bytes.
413 pub fn read_skip(&mut self, len: usize) -> ByteIOResult<()> {
414 if self.io.is_seekable() {
415 self.io.seek(SeekFrom::Current(len as i64))?;
416 } else {
417 let mut ssize = len;
418 let mut buf : [u8; 16] = [0; 16];
419 let bref = &mut buf;
420 while ssize > bref.len() {
421 self.io.read_buf(bref)?;
422 ssize -= bref.len();
423 }
424 while ssize > 0 {
425 self.io.read_byte()?;
426 ssize -= 1;
427 }
428 }
429 Ok(())
430 }
431
432 /// Returns current read position.
433 pub fn tell(&mut self) -> u64 {
434 self.io.tell()
435 }
436
437 /// Seeks to the provided position.
438 pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
439 self.io.seek(pos)
440 }
441
442 /// Tells whether this is end of stream.
443 pub fn is_eof(&self) -> bool {
444 self.io.is_eof()
445 }
446
447 /// Returns stream size or -1 if it is not known.
448 pub fn size(&mut self) -> i64 {
449 self.io.size()
450 }
451
452 /// Reports number of bytes left in the stream.
453 pub fn left(&mut self) -> i64 {
454 let size = self.io.size();
455 if size == -1 { return -1; }
456 size - (self.io.tell() as i64)
457 }
458 }
459
460 impl<'a> MemoryReader<'a> {
461 /// Constructs a new instance of `MemoryReader`.
462 pub fn new_read(buf: &'a [u8]) -> Self {
463 MemoryReader { buf, pos: 0 }
464 }
465
466 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
467 if pos < 0 || (pos as usize) > self.buf.len() {
468 return Err(ByteIOError::WrongRange);
469 }
470 self.pos = pos as usize;
471 Ok(pos as u64)
472 }
473 }
474
475 impl<'a> ByteIO for MemoryReader<'a> {
476 fn read_byte(&mut self) -> ByteIOResult<u8> {
477 if self.is_eof() { return Err(ByteIOError::EOF); }
478 let res = self.buf[self.pos];
479 self.pos += 1;
480 Ok(res)
481 }
482
483 fn peek_byte(&mut self) -> ByteIOResult<u8> {
484 if self.is_eof() { return Err(ByteIOError::EOF); }
485 Ok(self.buf[self.pos])
486 }
487
488 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
489 let copy_size = if self.buf.len() - self.pos < buf.len() { self.buf.len() - self.pos } else { buf.len() };
490 if copy_size == 0 { return Err(ByteIOError::EOF); }
491 let dst = &mut buf[0..copy_size];
492 dst.copy_from_slice(&self.buf[self.pos..][..copy_size]);
493 Ok(copy_size)
494 }
495
496 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
497 let read_size = self.peek_buf(buf)?;
498 if read_size < buf.len() { return Err(ByteIOError::EOF); }
499 self.pos += read_size;
500 Ok(read_size)
501 }
502
503 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
504 let read_size = self.peek_buf(buf)?;
505 self.pos += read_size;
506 Ok(read_size)
507 }
508
509 #[allow(unused_variables)]
510 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
511 Err(ByteIOError::NotImplemented)
512 }
513
514 fn tell(&mut self) -> u64 {
515 self.pos as u64
516 }
517
518 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
519 let cur_pos = self.pos as i64;
520 let cur_size = self.buf.len() as i64;
521 match pos {
522 SeekFrom::Start(x) => self.real_seek(x as i64),
523 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
524 SeekFrom::End(x) => self.real_seek(cur_size + x),
525 }
526 }
527
528 fn is_eof(&self) -> bool {
529 self.pos >= self.buf.len()
530 }
531
532 fn is_seekable(&mut self) -> bool {
533 true
534 }
535
536 fn size(&mut self) -> i64 {
537 self.buf.len() as i64
538 }
539 }
540
541 impl<'a> FileReader<'a> {
542
543 /// Constructs a new instance of `FileReader`.
544 pub fn new_read(file: &'a mut File) -> Self {
545 FileReader { file, eof : false }
546 }
547 }
548
549 impl<'a> ByteIO for FileReader<'a> {
550 fn read_byte(&mut self) -> ByteIOResult<u8> {
551 let mut byte : [u8; 1] = [0];
552 let ret = self.file.read(&mut byte);
553 if ret.is_err() { return Err(ByteIOError::ReadError); }
554 let sz = ret.unwrap();
555 if sz == 0 { self.eof = true; return Err(ByteIOError::EOF); }
556 Ok (byte[0])
557 }
558
559 fn peek_byte(&mut self) -> ByteIOResult<u8> {
560 let b = self.read_byte()?;
561 self.seek(SeekFrom::Current(-1))?;
562 Ok(b)
563 }
564
565 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
566 let ret = self.file.read(buf);
567 if ret.is_err() { return Err(ByteIOError::ReadError); }
568 let sz = ret.unwrap();
569 if sz < buf.len() { self.eof = true; return Err(ByteIOError::EOF); }
570 Ok(sz)
571 }
572
573 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
574 let ret = self.file.read(buf);
575 if ret.is_err() { return Err(ByteIOError::ReadError); }
576 let sz = ret.unwrap();
577 if sz < buf.len() { self.eof = true; }
578 Ok(sz)
579 }
580
581 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
582 let size = self.read_buf(buf)?;
583 self.seek(SeekFrom::Current(-(size as i64)))?;
584 Ok(size)
585 }
586
587 #[allow(unused_variables)]
588 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
589 Err(ByteIOError::NotImplemented)
590 }
591
592 fn tell(&mut self) -> u64 {
593 self.file.seek(SeekFrom::Current(0)).unwrap()
594 }
595
596 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
597 let res = self.file.seek(pos);
598 match res {
599 Ok(r) => Ok(r),
600 Err(_) => Err(ByteIOError::SeekError),
601 }
602 }
603
604 fn is_eof(&self) -> bool {
605 self.eof
606 }
607
608 fn is_seekable(&mut self) -> bool {
609 true
610 }
611
612 fn size(&mut self) -> i64 {
613 -1
614 }
615 }
616
617 /// High-level bytestream writer.
618 ///
619 /// User is supposed to create some writer implementing [`ByteIO`] trait e.g. [`MemoryWriter`] and use it to create `ByteWriter` which can be used for writing e.g. various integer types.
620 ///
621 /// # Examples
622 ///
623 /// ````
624 /// use nihav_core::io::byteio::{MemoryWriter,ByteWriter};
625 /// # use nihav_core::io::byteio::ByteIOResult;
626 ///
627 /// # fn foo() -> ByteIOResult<()> {
628 /// let mut memory = [0u8; 4];
629 /// let mut mw = MemoryWriter::new_write(&mut memory);
630 /// let mut bw = ByteWriter::new(&mut mw);
631 /// let val = bw.write_u16be(42)?; // memory should be [ 0, 42, 0, 0 ]
632 /// let val = bw.write_u16le(42)?; // memory should be [ 0, 42, 42, 0 ]
633 /// # Ok(())
634 /// # }
635 /// ````
636 ///
637 /// [`ByteIO`]: ./trait.ByteIO.html
638 /// [`MemoryWriter`]: ./struct.MemoryWriter.html
639 #[allow(dead_code)]
640 pub struct ByteWriter<'a> {
641 io: &'a mut ByteIO,
642 }
643
644 /// Bytestream writer to memory.
645 pub struct MemoryWriter<'a> {
646 buf: &'a mut [u8],
647 pos: usize,
648 }
649
650 /// Bytestream writer to file.
651 pub struct FileWriter {
652 file: File,
653 }
654
655 impl<'a> ByteWriter<'a> {
656 /// Constructs a new instance of `ByteWriter`.
657 pub fn new(io: &'a mut ByteIO) -> Self { ByteWriter { io } }
658
659 /// Writes byte array to the output.
660 pub fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
661 self.io.write_buf(buf)
662 }
663
664 /// Writes single byte to the output.
665 pub fn write_byte(&mut self, val: u8) -> ByteIOResult<()> {
666 let buf: [u8; 1] = [val];
667 self.io.write_buf(&buf)
668 }
669
670 /// Writes 16-bit big-endian integer to the output.
671 pub fn write_u16be(&mut self, val: u16) -> ByteIOResult<()> {
672 let buf: [u8; 2] = [((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
673 self.io.write_buf(&buf)
674 }
675
676 /// Writes 16-bit little-endian integer to the output.
677 pub fn write_u16le(&mut self, val: u16) -> ByteIOResult<()> {
678 let buf: [u8; 2] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8];
679 self.io.write_buf(&buf)
680 }
681
682 /// Writes 24-bit big-endian integer to the output.
683 pub fn write_u24be(&mut self, val: u32) -> ByteIOResult<()> {
684 let buf: [u8; 3] = [((val >> 16) & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
685 self.write_buf(&buf)
686 }
687
688 /// Writes 24-bit little-endian integer to the output.
689 pub fn write_u24le(&mut self, val: u32) -> ByteIOResult<()> {
690 let buf: [u8; 3] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, ((val >> 16) & 0xFF) as u8];
691 self.write_buf(&buf)
692 }
693
694 /// Writes 32-bit big-endian integer to the output.
695 pub fn write_u32be(&mut self, val: u32) -> ByteIOResult<()> {
696 self.write_u16be(((val >> 16) & 0xFFFF) as u16)?;
697 self.write_u16be((val & 0xFFFF) as u16)
698 }
699
700 /// Writes 32-bit little-endian integer to the output.
701 pub fn write_u32le(&mut self, val: u32) -> ByteIOResult<()> {
702 self.write_u16le((val & 0xFFFF) as u16)?;
703 self.write_u16le(((val >> 16) & 0xFFFF) as u16)
704 }
705
706 /// Writes 64-bit big-endian integer to the output.
707 pub fn write_u64be(&mut self, val: u64) -> ByteIOResult<()> {
708 self.write_u32be((val >> 32) as u32)?;
709 self.write_u32be(val as u32)
710 }
711
712 /// Writes 64-bit little-endian integer to the output.
713 pub fn write_u64le(&mut self, val: u64) -> ByteIOResult<()> {
714 self.write_u32le(val as u32)?;
715 self.write_u32le((val >> 32) as u32)
716 }
717
718 /// Writes 32-bit big-endian floating point number to the output.
719 pub fn write_f32be(&mut self, val: f32) -> ByteIOResult<()> {
720 self.write_u32be(val.to_bits())
721 }
722
723 /// Writes 32-bit little-endian floating point number to the output.
724 pub fn write_f32le(&mut self, val: f32) -> ByteIOResult<()> {
725 self.write_u32le(val.to_bits())
726 }
727
728 /// Writes 64-bit big-endian floating point number to the output.
729 pub fn write_f64be(&mut self, val: f64) -> ByteIOResult<()> {
730 self.write_u64be(val.to_bits())
731 }
732
733 /// Writes 64-bit little-endian floating point number to the output.
734 pub fn write_f64le(&mut self, val: f64) -> ByteIOResult<()> {
735 self.write_u64le(val.to_bits())
736 }
737
738 /// Reports the current write position.
739 pub fn tell(&mut self) -> u64 {
740 self.io.tell()
741 }
742
743 /// Seeks to the requested position.
744 pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
745 self.io.seek(pos)
746 }
747
748 /// Reports the amount of bytes the writer can still write (-1 if unknown).
749 pub fn size_left(&mut self) -> i64 {
750 let sz = self.io.size();
751 if sz == -1 { return -1; }
752 sz - (self.tell() as i64)
753 }
754 }
755
756 impl<'a> MemoryWriter<'a> {
757
758 /// Constructs a new instance of `MemoryWriter`.
759 pub fn new_write(buf: &'a mut [u8]) -> Self {
760 MemoryWriter { buf, pos: 0 }
761 }
762
763 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
764 if pos < 0 || (pos as usize) > self.buf.len() {
765 return Err(ByteIOError::WrongRange)
766 }
767 self.pos = pos as usize;
768 Ok(pos as u64)
769 }
770 }
771
772 impl<'a> ByteIO for MemoryWriter<'a> {
773 #[allow(unused_variables)]
774 fn read_byte(&mut self) -> ByteIOResult<u8> {
775 Err(ByteIOError::NotImplemented)
776 }
777
778 #[allow(unused_variables)]
779 fn peek_byte(&mut self) -> ByteIOResult<u8> {
780 Err(ByteIOError::NotImplemented)
781 }
782
783 #[allow(unused_variables)]
784 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
785 Err(ByteIOError::NotImplemented)
786 }
787
788 #[allow(unused_variables)]
789 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
790 Err(ByteIOError::NotImplemented)
791 }
792
793 #[allow(unused_variables)]
794 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
795 Err(ByteIOError::NotImplemented)
796 }
797
798 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
799 if self.pos + buf.len() > self.buf.len() { return Err(ByteIOError::WriteError); }
800 for i in 0..buf.len() {
801 self.buf[self.pos + i] = buf[i];
802 }
803 self.pos += buf.len();
804 Ok(())
805 }
806
807 fn tell(&mut self) -> u64 {
808 self.pos as u64
809 }
810
811 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
812 let cur_pos = self.pos as i64;
813 let cur_size = self.buf.len() as i64;
814 match pos {
815 SeekFrom::Start(x) => self.real_seek(x as i64),
816 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
817 SeekFrom::End(x) => self.real_seek(cur_size + x),
818 }
819 }
820
821 fn is_eof(&self) -> bool {
822 self.pos >= self.buf.len()
823 }
824
825 fn is_seekable(&mut self) -> bool {
826 true
827 }
828
829 fn size(&mut self) -> i64 {
830 self.buf.len() as i64
831 }
832 }
833
834 impl FileWriter {
835 /// Constructs a new instance of `FileWriter`.
836 pub fn new_write(file: File) -> Self {
837 FileWriter { file }
838 }
839 }
840
841 impl ByteIO for FileWriter {
842 #[allow(unused_variables)]
843 fn read_byte(&mut self) -> ByteIOResult<u8> {
844 Err(ByteIOError::NotImplemented)
845 }
846
847 #[allow(unused_variables)]
848 fn peek_byte(&mut self) -> ByteIOResult<u8> {
849 Err(ByteIOError::NotImplemented)
850 }
851
852 #[allow(unused_variables)]
853 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
854 Err(ByteIOError::NotImplemented)
855 }
856
857 #[allow(unused_variables)]
858 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
859 Err(ByteIOError::NotImplemented)
860 }
861
862 #[allow(unused_variables)]
863 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
864 Err(ByteIOError::NotImplemented)
865 }
866
867 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
868 match self.file.write_all(buf) {
869 Ok(()) => Ok(()),
870 Err(_) => Err(ByteIOError::WriteError),
871 }
872 }
873
874 fn tell(&mut self) -> u64 {
875 self.file.seek(SeekFrom::Current(0)).unwrap()
876 }
877
878 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
879 let res = self.file.seek(pos);
880 match res {
881 Ok(r) => Ok(r),
882 Err(_) => Err(ByteIOError::SeekError),
883 }
884 }
885
886 fn is_eof(&self) -> bool {
887 false
888 }
889
890 fn is_seekable(&mut self) -> bool {
891 true
892 }
893
894 fn size(&mut self) -> i64 {
895 -1
896 }
897 }
898
899 #[cfg(test)]
900 mod test {
901 use super::*;
902 use std::fs::File;
903
904 #[test]
905 fn test_read() {
906 //const DATA : &'static [u8] = include_bytes!("../../assets/file");
907 let buf: [u8; 64] = [1; 64];
908 let mut mr = MemoryReader::new_read(&buf);
909 let mut reader = ByteReader::new(&mut mr);
910 assert_eq!(reader.read_byte().unwrap(), 0x01u8);
911 assert_eq!(reader.read_u16le().unwrap(), 0x0101u16);
912 assert_eq!(reader.read_u24le().unwrap(), 0x010101u32);
913 assert_eq!(reader.read_u32le().unwrap(), 0x01010101u32);
914 assert_eq!(reader.read_u64le().unwrap(), 0x0101010101010101u64);
915 let mut file = File::open("assets/Misc/MaoMacha.asx").unwrap();
916 let mut fr = FileReader::new_read(&mut file);
917 let mut br2 = ByteReader::new(&mut fr);
918 assert_eq!(br2.read_byte().unwrap(), 0x30);
919 assert_eq!(br2.read_u24be().unwrap(), 0x26B275);
920 assert_eq!(br2.read_u24le().unwrap(), 0xCF668E);
921 assert_eq!(br2.read_u32be().unwrap(), 0x11A6D900);
922 assert_eq!(br2.read_u32le().unwrap(), 0xCE6200AA);
923 }
924 #[test]
925 fn test_write() {
926 let mut buf: [u8; 64] = [0; 64];
927 {
928 let mut mw = MemoryWriter::new_write(&mut buf);
929 let mut bw = ByteWriter::new(&mut mw);
930 bw.write_byte(0x00).unwrap();
931 bw.write_u16be(0x0102).unwrap();
932 bw.write_u24be(0x030405).unwrap();
933 bw.write_u32be(0x06070809).unwrap();
934 bw.write_u64be(0x0A0B0C0D0E0F1011).unwrap();
935 bw.write_byte(0x00).unwrap();
936 bw.write_u16le(0x0201).unwrap();
937 bw.write_u24le(0x050403).unwrap();
938 bw.write_u32le(0x09080706).unwrap();
939 bw.write_u64le(0x11100F0E0D0C0B0A).unwrap();
940 assert_eq!(bw.size_left(), 28);
941 }
942 for i in 0..0x12 {
943 assert_eq!(buf[(i + 0x00) as usize], i);
944 assert_eq!(buf[(i + 0x12) as usize], i);
945 }
946 }
947 }