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