core: fix or silence clippy warnings
[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 #[allow(clippy::identity_op)]
204 pub fn write_u24be(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
205 if dst.len() < 3 { return Err(ByteIOError::WriteError); }
206 dst[0] = (val >> 16) as u8;
207 dst[1] = (val >> 8) as u8;
208 dst[2] = (val >> 0) as u8;
209 Ok(())
210 }
211 /// Writes 24-bit little-endian integer to the provided buffer.
212 #[allow(clippy::identity_op)]
213 pub fn write_u24le(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
214 if dst.len() < 3 { return Err(ByteIOError::WriteError); }
215 dst[0] = (val >> 0) as u8;
216 dst[1] = (val >> 8) as u8;
217 dst[2] = (val >> 16) as u8;
218 Ok(())
219 }
220 /// Writes 32-bit big-endian floating point number to the provided buffer.
221 pub fn write_f32be(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32be(dst, val.to_bits()) }
222 /// Writes 32-bit little-endian floating point number to the provided buffer.
223 pub fn write_f32le(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32le(dst, val.to_bits()) }
224 /// Writes 64-bit big-endian floating point number to the provided buffer.
225 pub fn write_f64be(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64be(dst, val.to_bits()) }
226 /// Writes 64-bit little-endian floating point number to the provided buffer.
227 pub fn write_f64le(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64le(dst, val.to_bits()) }
228
229 impl<'a> ByteReader<'a> {
230 /// Constructs a new instance of bytestream reader.
231 ///
232 /// # Examples
233 ///
234 /// ````
235 /// use nihav_core::io::byteio::{MemoryReader,ByteReader};
236 /// # use nihav_core::io::byteio::ByteIOResult;
237 ///
238 /// # fn foo() -> ByteIOResult<()> {
239 /// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
240 /// let mut mr = MemoryReader::new_read(&memory);
241 /// let mut br = ByteReader::new(&mut mr);
242 /// # Ok(())
243 /// # }
244 /// ````
245 pub fn new(io: &'a mut ByteIO) -> Self { ByteReader { io } }
246
247 /// Reads data into provided buffer. Partial read is treated as success.
248 pub fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
249 self.io.read_buf(buf)
250 }
251
252 /// Reads data into provided buffer. Partial read is treated as success.
253 pub fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
254 self.io.read_buf_some(buf)
255 }
256
257 /// Reads data into provided buffer but does not advance read position.
258 pub fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
259 self.io.peek_buf(buf)
260 }
261
262 /// Reads single byte from the stream.
263 pub fn read_byte(&mut self) -> ByteIOResult<u8> {
264 self.io.read_byte()
265 }
266
267 /// Returns the next byte value in the stream without advancing read position.
268 pub fn peek_byte(&mut self) -> ByteIOResult<u8> {
269 self.io.peek_byte()
270 }
271
272 /// Reads four-byte array from the stream.
273 pub fn read_tag(&mut self) -> ByteIOResult<[u8; 4]> {
274 let mut buf = [0u8; 4];
275 self.io.read_buf(&mut buf)?;
276 Ok(buf)
277 }
278
279 /// Reads four-byte array from the stream without advancing read position.
280 pub fn peek_tag(&mut self) -> ByteIOResult<[u8; 4]> {
281 let mut buf = [0u8; 4];
282 self.io.peek_buf(&mut buf)?;
283 Ok(buf)
284 }
285
286 /// Reads 16-bit big-endian integer from the stream.
287 pub fn read_u16be(&mut self) -> ByteIOResult<u16> {
288 read_int!(self, u16, 2, to_be)
289 }
290
291 /// Reads 16-bit big-endian integer from the stream without advancing read position.
292 pub fn peek_u16be(&mut self) -> ByteIOResult<u16> {
293 peek_int!(self, u16, 2, to_be)
294 }
295
296 /// Reads 24-bit big-endian integer from the stream.
297 pub fn read_u24be(&mut self) -> ByteIOResult<u32> {
298 let p16 = self.read_u16be()?;
299 let p8 = self.read_byte()?;
300 Ok((u32::from(p16) << 8) | u32::from(p8))
301 }
302
303 /// Reads 24-bit big-endian integer from the stream without advancing read position.
304 pub fn peek_u24be(&mut self) -> ByteIOResult<u32> {
305 let mut src: [u8; 3] = [0; 3];
306 self.peek_buf(&mut src)?;
307 Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
308 }
309
310 /// Reads 32-bit big-endian integer from the stream.
311 pub fn read_u32be(&mut self) -> ByteIOResult<u32> {
312 read_int!(self, u32, 4, to_be)
313 }
314
315 /// Reads 32-bit big-endian integer from the stream without advancing read position.
316 pub fn peek_u32be(&mut self) -> ByteIOResult<u32> {
317 peek_int!(self, u32, 4, to_be)
318 }
319
320 /// Reads 64-bit big-endian integer from the stream.
321 pub fn read_u64be(&mut self) -> ByteIOResult<u64> {
322 read_int!(self, u64, 8, to_be)
323 }
324
325 /// Reads 64-bit big-endian integer from the stream without advancing read position.
326 pub fn peek_u64be(&mut self) -> ByteIOResult<u64> {
327 peek_int!(self, u64, 8, to_be)
328 }
329
330 /// Reads 32-bit big-endian floating point number from the stream.
331 pub fn read_f32be(&mut self) -> ByteIOResult<f32> {
332 Ok(f32::from_bits(self.read_u32be()?))
333 }
334
335 /// Reads 32-bit big-endian floating point number from the stream without advancing read position.
336 pub fn peek_f32be(&mut self) -> ByteIOResult<f32> {
337 Ok(f32::from_bits(self.peek_u32be()?))
338 }
339
340 /// Reads 64-bit big-endian floating point number from the stream.
341 pub fn read_f64be(&mut self) -> ByteIOResult<f64> {
342 Ok(f64::from_bits(self.read_u64be()?))
343 }
344
345 /// Reads 64-bit big-endian floating point number from the stream without advancing read position.
346 pub fn peek_f64be(&mut self) -> ByteIOResult<f64> {
347 Ok(f64::from_bits(self.peek_u64be()?))
348 }
349
350 /// Reads 16-bit little-endian integer from the stream.
351 pub fn read_u16le(&mut self) -> ByteIOResult<u16> {
352 read_int!(self, u16, 2, to_le)
353 }
354
355 /// Reads 16-bit little-endian integer from the stream without advancing read position.
356 pub fn peek_u16le(&mut self) -> ByteIOResult<u16> {
357 peek_int!(self, u16, 2, to_le)
358 }
359
360 /// Reads 24-bit little-endian integer from the stream.
361 pub fn read_u24le(&mut self) -> ByteIOResult<u32> {
362 let p8 = self.read_byte()?;
363 let p16 = self.read_u16le()?;
364 Ok((u32::from(p16) << 8) | u32::from(p8))
365 }
366
367 /// Reads 24-bit little-endian integer from the stream without advancing read position.
368 pub fn peek_u24le(&mut self) -> ByteIOResult<u32> {
369 let mut src: [u8; 3] = [0; 3];
370 self.peek_buf(&mut src)?;
371 Ok(u32::from(src[0]) | (u32::from(src[1]) << 8) | (u32::from(src[2]) << 16))
372 }
373
374 /// Reads 32-bit little-endian integer from the stream.
375 pub fn read_u32le(&mut self) -> ByteIOResult<u32> {
376 read_int!(self, u32, 4, to_le)
377 }
378
379 /// Reads 32-bit little-endian integer from the stream without advancing read position.
380 pub fn peek_u32le(&mut self) -> ByteIOResult<u32> {
381 peek_int!(self, u32, 4, to_le)
382 }
383
384 /// Reads 64-bit little-endian integer from the stream.
385 pub fn read_u64le(&mut self) -> ByteIOResult<u64> {
386 read_int!(self, u64, 8, to_le)
387 }
388
389 /// Reads 64-bit little-endian integer from the stream without advancing read position.
390 pub fn peek_u64le(&mut self) -> ByteIOResult<u64> {
391 peek_int!(self, u64, 8, to_le)
392 }
393
394 /// Reads 32-bit little-endian floating point number from the stream.
395 pub fn read_f32le(&mut self) -> ByteIOResult<f32> {
396 Ok(f32::from_bits(self.read_u32le()?))
397 }
398
399 /// Reads 32-bit little-endian floating point number from the stream without advancing read position.
400 pub fn peek_f32le(&mut self) -> ByteIOResult<f32> {
401 Ok(f32::from_bits(self.peek_u32le()?))
402 }
403
404 /// Reads 64-bit little-endian floating point number from the stream.
405 pub fn read_f64le(&mut self) -> ByteIOResult<f64> {
406 Ok(f64::from_bits(self.read_u64le()?))
407 }
408
409 /// Reads 64-bit little-endian floating point number from the stream without advancing read position.
410 pub fn peek_f64le(&mut self) -> ByteIOResult<f64> {
411 Ok(f64::from_bits(self.peek_u64le()?))
412 }
413
414 /// Skips requested number of bytes.
415 pub fn read_skip(&mut self, len: usize) -> ByteIOResult<()> {
416 if self.io.is_seekable() {
417 self.io.seek(SeekFrom::Current(len as i64))?;
418 } else {
419 let mut ssize = len;
420 let mut buf : [u8; 16] = [0; 16];
421 let bref = &mut buf;
422 while ssize > bref.len() {
423 self.io.read_buf(bref)?;
424 ssize -= bref.len();
425 }
426 while ssize > 0 {
427 self.io.read_byte()?;
428 ssize -= 1;
429 }
430 }
431 Ok(())
432 }
433
434 /// Returns current read position.
435 pub fn tell(&mut self) -> u64 {
436 self.io.tell()
437 }
438
439 /// Seeks to the provided position.
440 pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
441 self.io.seek(pos)
442 }
443
444 /// Tells whether this is end of stream.
445 pub fn is_eof(&self) -> bool {
446 self.io.is_eof()
447 }
448
449 /// Returns stream size or -1 if it is not known.
450 pub fn size(&mut self) -> i64 {
451 self.io.size()
452 }
453
454 /// Reports number of bytes left in the stream.
455 pub fn left(&mut self) -> i64 {
456 let size = self.io.size();
457 if size == -1 { return -1; }
458 size - (self.io.tell() as i64)
459 }
460 }
461
462 impl<'a> MemoryReader<'a> {
463 /// Constructs a new instance of `MemoryReader`.
464 pub fn new_read(buf: &'a [u8]) -> Self {
465 MemoryReader { buf, pos: 0 }
466 }
467
468 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
469 if pos < 0 || (pos as usize) > self.buf.len() {
470 return Err(ByteIOError::WrongRange);
471 }
472 self.pos = pos as usize;
473 Ok(pos as u64)
474 }
475 }
476
477 impl<'a> ByteIO for MemoryReader<'a> {
478 fn read_byte(&mut self) -> ByteIOResult<u8> {
479 if self.is_eof() { return Err(ByteIOError::EOF); }
480 let res = self.buf[self.pos];
481 self.pos += 1;
482 Ok(res)
483 }
484
485 fn peek_byte(&mut self) -> ByteIOResult<u8> {
486 if self.is_eof() { return Err(ByteIOError::EOF); }
487 Ok(self.buf[self.pos])
488 }
489
490 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
491 let copy_size = if self.buf.len() - self.pos < buf.len() { self.buf.len() - self.pos } else { buf.len() };
492 if copy_size == 0 { return Err(ByteIOError::EOF); }
493 let dst = &mut buf[0..copy_size];
494 dst.copy_from_slice(&self.buf[self.pos..][..copy_size]);
495 Ok(copy_size)
496 }
497
498 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
499 let read_size = self.peek_buf(buf)?;
500 if read_size < buf.len() { return Err(ByteIOError::EOF); }
501 self.pos += read_size;
502 Ok(read_size)
503 }
504
505 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
506 let read_size = self.peek_buf(buf)?;
507 self.pos += read_size;
508 Ok(read_size)
509 }
510
511 #[allow(unused_variables)]
512 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
513 Err(ByteIOError::NotImplemented)
514 }
515
516 fn tell(&mut self) -> u64 {
517 self.pos as u64
518 }
519
520 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
521 let cur_pos = self.pos as i64;
522 let cur_size = self.buf.len() as i64;
523 match pos {
524 SeekFrom::Start(x) => self.real_seek(x as i64),
525 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
526 SeekFrom::End(x) => self.real_seek(cur_size + x),
527 }
528 }
529
530 fn is_eof(&self) -> bool {
531 self.pos >= self.buf.len()
532 }
533
534 fn is_seekable(&mut self) -> bool {
535 true
536 }
537
538 fn size(&mut self) -> i64 {
539 self.buf.len() as i64
540 }
541 }
542
543 impl<'a> FileReader<'a> {
544
545 /// Constructs a new instance of `FileReader`.
546 pub fn new_read(file: &'a mut File) -> Self {
547 FileReader { file, eof : false }
548 }
549 }
550
551 impl<'a> ByteIO for FileReader<'a> {
552 fn read_byte(&mut self) -> ByteIOResult<u8> {
553 let mut byte : [u8; 1] = [0];
554 let ret = self.file.read(&mut byte);
555 if ret.is_err() { return Err(ByteIOError::ReadError); }
556 let sz = ret.unwrap();
557 if sz == 0 { self.eof = true; return Err(ByteIOError::EOF); }
558 Ok (byte[0])
559 }
560
561 fn peek_byte(&mut self) -> ByteIOResult<u8> {
562 let b = self.read_byte()?;
563 self.seek(SeekFrom::Current(-1))?;
564 Ok(b)
565 }
566
567 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
568 let ret = self.file.read(buf);
569 if ret.is_err() { return Err(ByteIOError::ReadError); }
570 let sz = ret.unwrap();
571 if sz < buf.len() { self.eof = true; return Err(ByteIOError::EOF); }
572 Ok(sz)
573 }
574
575 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
576 let ret = self.file.read(buf);
577 if ret.is_err() { return Err(ByteIOError::ReadError); }
578 let sz = ret.unwrap();
579 if sz < buf.len() { self.eof = true; }
580 Ok(sz)
581 }
582
583 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
584 let size = self.read_buf(buf)?;
585 self.seek(SeekFrom::Current(-(size as i64)))?;
586 Ok(size)
587 }
588
589 #[allow(unused_variables)]
590 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
591 Err(ByteIOError::NotImplemented)
592 }
593
594 fn tell(&mut self) -> u64 {
595 self.file.seek(SeekFrom::Current(0)).unwrap()
596 }
597
598 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
599 let res = self.file.seek(pos);
600 match res {
601 Ok(r) => Ok(r),
602 Err(_) => Err(ByteIOError::SeekError),
603 }
604 }
605
606 fn is_eof(&self) -> bool {
607 self.eof
608 }
609
610 fn is_seekable(&mut self) -> bool {
611 true
612 }
613
614 fn size(&mut self) -> i64 {
615 -1
616 }
617 }
618
619 /// High-level bytestream writer.
620 ///
621 /// 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.
622 ///
623 /// # Examples
624 ///
625 /// ````
626 /// use nihav_core::io::byteio::{MemoryWriter,ByteWriter};
627 /// # use nihav_core::io::byteio::ByteIOResult;
628 ///
629 /// # fn foo() -> ByteIOResult<()> {
630 /// let mut memory = [0u8; 4];
631 /// let mut mw = MemoryWriter::new_write(&mut memory);
632 /// let mut bw = ByteWriter::new(&mut mw);
633 /// let val = bw.write_u16be(42)?; // memory should be [ 0, 42, 0, 0 ]
634 /// let val = bw.write_u16le(42)?; // memory should be [ 0, 42, 42, 0 ]
635 /// # Ok(())
636 /// # }
637 /// ````
638 ///
639 /// [`ByteIO`]: ./trait.ByteIO.html
640 /// [`MemoryWriter`]: ./struct.MemoryWriter.html
641 #[allow(dead_code)]
642 pub struct ByteWriter<'a> {
643 io: &'a mut ByteIO,
644 }
645
646 /// Bytestream writer to memory.
647 pub struct MemoryWriter<'a> {
648 buf: &'a mut [u8],
649 pos: usize,
650 }
651
652 /// Bytestream writer to file.
653 pub struct FileWriter {
654 file: File,
655 }
656
657 /// Bytestream writer to memory.
658 ///
659 /// Unlike [`MemoryWriter`] which writes to an array of fixed size, `GrowableMemoryWriter` grows output size when output size exceeds capacity.
660 ///
661 /// [`MemoryWriter`]: ./struct.MemoryWriter.html
662 pub struct GrowableMemoryWriter<'a> {
663 buf: &'a mut Vec<u8>,
664 pos: usize,
665 }
666
667 impl<'a> ByteWriter<'a> {
668 /// Constructs a new instance of `ByteWriter`.
669 pub fn new(io: &'a mut ByteIO) -> Self { ByteWriter { io } }
670
671 /// Writes byte array to the output.
672 pub fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
673 self.io.write_buf(buf)
674 }
675
676 /// Writes single byte to the output.
677 pub fn write_byte(&mut self, val: u8) -> ByteIOResult<()> {
678 let buf: [u8; 1] = [val];
679 self.io.write_buf(&buf)
680 }
681
682 /// Writes 16-bit big-endian integer to the output.
683 pub fn write_u16be(&mut self, val: u16) -> ByteIOResult<()> {
684 let buf: [u8; 2] = [((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
685 self.io.write_buf(&buf)
686 }
687
688 /// Writes 16-bit little-endian integer to the output.
689 pub fn write_u16le(&mut self, val: u16) -> ByteIOResult<()> {
690 let buf: [u8; 2] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8];
691 self.io.write_buf(&buf)
692 }
693
694 /// Writes 24-bit big-endian integer to the output.
695 pub fn write_u24be(&mut self, val: u32) -> ByteIOResult<()> {
696 let buf: [u8; 3] = [((val >> 16) & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
697 self.write_buf(&buf)
698 }
699
700 /// Writes 24-bit little-endian integer to the output.
701 pub fn write_u24le(&mut self, val: u32) -> ByteIOResult<()> {
702 let buf: [u8; 3] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, ((val >> 16) & 0xFF) as u8];
703 self.write_buf(&buf)
704 }
705
706 /// Writes 32-bit big-endian integer to the output.
707 pub fn write_u32be(&mut self, val: u32) -> ByteIOResult<()> {
708 self.write_u16be(((val >> 16) & 0xFFFF) as u16)?;
709 self.write_u16be((val & 0xFFFF) as u16)
710 }
711
712 /// Writes 32-bit little-endian integer to the output.
713 pub fn write_u32le(&mut self, val: u32) -> ByteIOResult<()> {
714 self.write_u16le((val & 0xFFFF) as u16)?;
715 self.write_u16le(((val >> 16) & 0xFFFF) as u16)
716 }
717
718 /// Writes 64-bit big-endian integer to the output.
719 pub fn write_u64be(&mut self, val: u64) -> ByteIOResult<()> {
720 self.write_u32be((val >> 32) as u32)?;
721 self.write_u32be(val as u32)
722 }
723
724 /// Writes 64-bit little-endian integer to the output.
725 pub fn write_u64le(&mut self, val: u64) -> ByteIOResult<()> {
726 self.write_u32le(val as u32)?;
727 self.write_u32le((val >> 32) as u32)
728 }
729
730 /// Writes 32-bit big-endian floating point number to the output.
731 pub fn write_f32be(&mut self, val: f32) -> ByteIOResult<()> {
732 self.write_u32be(val.to_bits())
733 }
734
735 /// Writes 32-bit little-endian floating point number to the output.
736 pub fn write_f32le(&mut self, val: f32) -> ByteIOResult<()> {
737 self.write_u32le(val.to_bits())
738 }
739
740 /// Writes 64-bit big-endian floating point number to the output.
741 pub fn write_f64be(&mut self, val: f64) -> ByteIOResult<()> {
742 self.write_u64be(val.to_bits())
743 }
744
745 /// Writes 64-bit little-endian floating point number to the output.
746 pub fn write_f64le(&mut self, val: f64) -> ByteIOResult<()> {
747 self.write_u64le(val.to_bits())
748 }
749
750 /// Reports the current write position.
751 pub fn tell(&mut self) -> u64 {
752 self.io.tell()
753 }
754
755 /// Seeks to the requested position.
756 pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
757 self.io.seek(pos)
758 }
759
760 /// Reports the amount of bytes the writer can still write (-1 if unknown).
761 pub fn size_left(&mut self) -> i64 {
762 let sz = self.io.size();
763 if sz == -1 { return -1; }
764 sz - (self.tell() as i64)
765 }
766 }
767
768 impl<'a> MemoryWriter<'a> {
769
770 /// Constructs a new instance of `MemoryWriter`.
771 pub fn new_write(buf: &'a mut [u8]) -> Self {
772 MemoryWriter { buf, pos: 0 }
773 }
774
775 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
776 if pos < 0 || (pos as usize) > self.buf.len() {
777 return Err(ByteIOError::WrongRange)
778 }
779 self.pos = pos as usize;
780 Ok(pos as u64)
781 }
782 }
783
784 impl<'a> ByteIO for MemoryWriter<'a> {
785 #[allow(unused_variables)]
786 fn read_byte(&mut self) -> ByteIOResult<u8> {
787 Err(ByteIOError::NotImplemented)
788 }
789
790 #[allow(unused_variables)]
791 fn peek_byte(&mut self) -> ByteIOResult<u8> {
792 Err(ByteIOError::NotImplemented)
793 }
794
795 #[allow(unused_variables)]
796 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
797 Err(ByteIOError::NotImplemented)
798 }
799
800 #[allow(unused_variables)]
801 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
802 Err(ByteIOError::NotImplemented)
803 }
804
805 #[allow(unused_variables)]
806 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
807 Err(ByteIOError::NotImplemented)
808 }
809
810 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
811 if self.pos + buf.len() > self.buf.len() { return Err(ByteIOError::WriteError); }
812 self.buf[self.pos..][..buf.len()].copy_from_slice(buf);
813 self.pos += buf.len();
814 Ok(())
815 }
816
817 fn tell(&mut self) -> u64 {
818 self.pos as u64
819 }
820
821 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
822 let cur_pos = self.pos as i64;
823 let cur_size = self.buf.len() as i64;
824 match pos {
825 SeekFrom::Start(x) => self.real_seek(x as i64),
826 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
827 SeekFrom::End(x) => self.real_seek(cur_size + x),
828 }
829 }
830
831 fn is_eof(&self) -> bool {
832 self.pos >= self.buf.len()
833 }
834
835 fn is_seekable(&mut self) -> bool {
836 true
837 }
838
839 fn size(&mut self) -> i64 {
840 self.buf.len() as i64
841 }
842 }
843
844 impl<'a> GrowableMemoryWriter<'a> {
845
846 /// Constructs a new instance of `GrowableMemoryWriter`.
847 pub fn new_write(buf: &'a mut Vec<u8>) -> Self {
848 GrowableMemoryWriter { buf, pos: 0 }
849 }
850
851 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
852 if pos < 0 || (pos as usize) > self.buf.len() {
853 return Err(ByteIOError::WrongRange)
854 }
855 self.pos = pos as usize;
856 Ok(pos as u64)
857 }
858 }
859
860 impl<'a> ByteIO for GrowableMemoryWriter<'a> {
861 #[allow(unused_variables)]
862 fn read_byte(&mut self) -> ByteIOResult<u8> {
863 Err(ByteIOError::NotImplemented)
864 }
865
866 #[allow(unused_variables)]
867 fn peek_byte(&mut self) -> ByteIOResult<u8> {
868 Err(ByteIOError::NotImplemented)
869 }
870
871 #[allow(unused_variables)]
872 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
873 Err(ByteIOError::NotImplemented)
874 }
875
876 #[allow(unused_variables)]
877 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
878 Err(ByteIOError::NotImplemented)
879 }
880
881 #[allow(unused_variables)]
882 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
883 Err(ByteIOError::NotImplemented)
884 }
885
886 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
887 if self.pos + buf.len() > self.buf.len() {
888 self.buf.resize(self.pos + buf.len(), 0);
889 }
890 self.buf[self.pos..][..buf.len()].copy_from_slice(buf);
891 self.pos += buf.len();
892 Ok(())
893 }
894
895 fn tell(&mut self) -> u64 {
896 self.pos as u64
897 }
898
899 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
900 let cur_pos = self.pos as i64;
901 let cur_size = self.buf.len() as i64;
902 match pos {
903 SeekFrom::Start(x) => self.real_seek(x as i64),
904 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
905 SeekFrom::End(x) => self.real_seek(cur_size + x),
906 }
907 }
908
909 fn is_eof(&self) -> bool {
910 self.pos >= self.buf.len()
911 }
912
913 fn is_seekable(&mut self) -> bool {
914 true
915 }
916
917 fn size(&mut self) -> i64 {
918 self.buf.len() as i64
919 }
920 }
921
922 impl FileWriter {
923 /// Constructs a new instance of `FileWriter`.
924 pub fn new_write(file: File) -> Self {
925 FileWriter { file }
926 }
927 }
928
929 impl ByteIO for FileWriter {
930 #[allow(unused_variables)]
931 fn read_byte(&mut self) -> ByteIOResult<u8> {
932 Err(ByteIOError::NotImplemented)
933 }
934
935 #[allow(unused_variables)]
936 fn peek_byte(&mut self) -> ByteIOResult<u8> {
937 Err(ByteIOError::NotImplemented)
938 }
939
940 #[allow(unused_variables)]
941 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
942 Err(ByteIOError::NotImplemented)
943 }
944
945 #[allow(unused_variables)]
946 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
947 Err(ByteIOError::NotImplemented)
948 }
949
950 #[allow(unused_variables)]
951 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
952 Err(ByteIOError::NotImplemented)
953 }
954
955 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
956 match self.file.write_all(buf) {
957 Ok(()) => Ok(()),
958 Err(_) => Err(ByteIOError::WriteError),
959 }
960 }
961
962 fn tell(&mut self) -> u64 {
963 self.file.seek(SeekFrom::Current(0)).unwrap()
964 }
965
966 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
967 let res = self.file.seek(pos);
968 match res {
969 Ok(r) => Ok(r),
970 Err(_) => Err(ByteIOError::SeekError),
971 }
972 }
973
974 fn is_eof(&self) -> bool {
975 false
976 }
977
978 fn is_seekable(&mut self) -> bool {
979 true
980 }
981
982 fn size(&mut self) -> i64 {
983 -1
984 }
985 }
986
987 #[cfg(test)]
988 mod test {
989 use super::*;
990 use std::fs::File;
991
992 #[test]
993 fn test_read() {
994 //const DATA : &'static [u8] = include_bytes!("../../assets/file");
995 let buf: [u8; 64] = [1; 64];
996 let mut mr = MemoryReader::new_read(&buf);
997 let mut reader = ByteReader::new(&mut mr);
998 assert_eq!(reader.read_byte().unwrap(), 0x01u8);
999 assert_eq!(reader.read_u16le().unwrap(), 0x0101u16);
1000 assert_eq!(reader.read_u24le().unwrap(), 0x010101u32);
1001 assert_eq!(reader.read_u32le().unwrap(), 0x01010101u32);
1002 assert_eq!(reader.read_u64le().unwrap(), 0x0101010101010101u64);
1003 let mut file = File::open("assets/Misc/MaoMacha.asx").unwrap();
1004 let mut fr = FileReader::new_read(&mut file);
1005 let mut br2 = ByteReader::new(&mut fr);
1006 assert_eq!(br2.read_byte().unwrap(), 0x30);
1007 assert_eq!(br2.read_u24be().unwrap(), 0x26B275);
1008 assert_eq!(br2.read_u24le().unwrap(), 0xCF668E);
1009 assert_eq!(br2.read_u32be().unwrap(), 0x11A6D900);
1010 assert_eq!(br2.read_u32le().unwrap(), 0xCE6200AA);
1011 }
1012 #[test]
1013 fn test_write() {
1014 let mut buf: [u8; 64] = [0; 64];
1015 {
1016 let mut mw = MemoryWriter::new_write(&mut buf);
1017 let mut bw = ByteWriter::new(&mut mw);
1018 bw.write_byte(0x00).unwrap();
1019 bw.write_u16be(0x0102).unwrap();
1020 bw.write_u24be(0x030405).unwrap();
1021 bw.write_u32be(0x06070809).unwrap();
1022 bw.write_u64be(0x0A0B0C0D0E0F1011).unwrap();
1023 bw.write_byte(0x00).unwrap();
1024 bw.write_u16le(0x0201).unwrap();
1025 bw.write_u24le(0x050403).unwrap();
1026 bw.write_u32le(0x09080706).unwrap();
1027 bw.write_u64le(0x11100F0E0D0C0B0A).unwrap();
1028 assert_eq!(bw.size_left(), 28);
1029 }
1030 for i in 0..0x12 {
1031 assert_eq!(buf[(i + 0x00) as usize], i);
1032 assert_eq!(buf[(i + 0x12) as usize], i);
1033 }
1034 }
1035 }