]> git.nihav.org Git - nihav.git/commitdiff
nihav_core/io: merge ByteReader/ByteWriter functionality into ByteIO
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sun, 17 Aug 2025 15:59:34 +0000 (17:59 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sun, 17 Aug 2025 15:59:34 +0000 (17:59 +0200)
nihav-core/src/compr/deflate.rs
nihav-core/src/demuxers/mod.rs
nihav-core/src/io/byteio.rs
nihav-core/src/muxers/mod.rs

index 80a84d8472ba60171482c6f196cbf3446145168e..72c583b48d525554477065ddff136100d462ee21 100644 (file)
@@ -1066,7 +1066,7 @@ impl GzipCRC32 {
 }
 
 /// Decodes input data in gzip file format (RFC 1952) returning a vector containing decoded data.
-pub fn gzip_decode(br: &mut ByteReader, skip_crc: bool) -> DecompressResult<Vec<u8>> {
+pub fn gzip_decode(br: &mut dyn ByteIO, skip_crc: bool) -> DecompressResult<Vec<u8>> {
     const FLAG_HCRC:    u8 = 0x02;
     const FLAG_EXTRA:   u8 = 0x04;
     const FLAG_NAME:    u8 = 0x08;
@@ -2212,8 +2212,7 @@ mod test {
     0x8B, 0x65, 0x00, 0xB7, 0x36, 0xBD, 0x77, 0xA8, 0xBD, 0x5A, 0xAA, 0x1A, 0x09, 0x00, 0x00
         ];
 
-        let mut mr = MemoryReader::new_read(TEST_DATA);
-        let mut br = ByteReader::new(&mut mr);
+        let mut br = MemoryReader::new_read(TEST_DATA);
         let _dst_buf = gzip_decode(&mut br, false).unwrap();
 
 //        println!("{}", String::from_utf8_lossy(_dst_buf.as_slice()));
index 08bf8f7353a9eaff9a5a98ae93eade6193f7ffdf..12ebdd0f96c6e16773042e6b3d2ec978820ec654 100644 (file)
@@ -50,7 +50,7 @@ pub trait NAPacketReader {
     fn fill_packet(&mut self, pkt: &mut NAPacket) -> DemuxerResult<()>;
 }
 
-impl<'a> NAPacketReader for ByteReader<'a> {
+impl<T: ?Sized + ByteIO> NAPacketReader for T {
     fn read_packet(&mut self, strm: NAStreamRef, ts: NATimeInfo, kf: bool, size: usize) -> DemuxerResult<NAPacket> {
         let mut buf: Vec<u8> = Vec::with_capacity(size);
         if buf.capacity() < size { return Err(DemuxerError::MemoryError); }
@@ -448,14 +448,14 @@ impl From<ByteIOError> for DemuxerError {
 
 /// The trait for creating demuxers.
 pub trait DemuxerCreator {
-    /// Creates new demuxer instance that will use `ByteReader` source as an input.
-    fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a>;
+    /// Creates new demuxer instance that will use source with `ByteIO` trait as an input.
+    fn new_demuxer<'a>(&self, br: &'a mut dyn ByteIO) -> Box<dyn DemuxCore<'a> + 'a>;
     /// Returns the name of current demuxer creator (equal to the container name it can demux).
     fn get_name(&self) -> &'static str;
 }
 
 /// Creates demuxer for a provided bytestream.
-pub fn create_demuxer<'a>(dmxcr: &dyn DemuxerCreator, br: &'a mut ByteReader<'a>) -> DemuxerResult<Demuxer<'a>> {
+pub fn create_demuxer<'a>(dmxcr: &dyn DemuxerCreator, br: &'a mut dyn ByteIO) -> DemuxerResult<Demuxer<'a>> {
     let mut dmx = dmxcr.new_demuxer(br);
     let mut strmgr = StreamManager::new();
     let mut seek_idx = SeekIndex::new();
@@ -464,7 +464,7 @@ pub fn create_demuxer<'a>(dmxcr: &dyn DemuxerCreator, br: &'a mut ByteReader<'a>
 }
 
 /// Creates demuxer for a provided bytestream with options applied right after its creation.
-pub fn create_demuxer_with_options<'a>(dmxcr: &dyn DemuxerCreator, br: &'a mut ByteReader<'a>, opts: &[NAOption]) -> DemuxerResult<Demuxer<'a>> {
+pub fn create_demuxer_with_options<'a>(dmxcr: &dyn DemuxerCreator, br: &'a mut dyn ByteIO, opts: &[NAOption]) -> DemuxerResult<Demuxer<'a>> {
     let mut dmx = dmxcr.new_demuxer(br);
     dmx.set_options(opts);
     let mut strmgr = StreamManager::new();
@@ -617,16 +617,16 @@ impl<'a> NAOptionHandler for RawDemuxer<'a> {
 
 /// The trait for creating raw data demuxers.
 pub trait RawDemuxerCreator {
-    /// Creates new raw demuxer instance that will use `ByteReader` source as an input.
-    fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn RawDemuxCore<'a> + 'a>;
+    /// Creates new raw demuxer instance that will use source with `ByteIO` trait as an input.
+    fn new_demuxer<'a>(&self, br: &'a mut dyn ByteIO) -> Box<dyn RawDemuxCore<'a> + 'a>;
     /// Tries to check whether the input can be demuxed with the demuxer.
-    fn check_format(&self, br: &mut ByteReader) -> bool;
+    fn check_format(&self, br: &mut dyn ByteIO) -> bool;
     /// Returns the name of current raw data demuxer creator (equal to the container name it can demux).
     fn get_name(&self) -> &'static str;
 }
 
 /// Creates raw data demuxer for a provided bytestream.
-pub fn create_raw_demuxer<'a>(dmxcr: &dyn RawDemuxerCreator, br: &'a mut ByteReader<'a>) -> DemuxerResult<RawDemuxer<'a>> {
+pub fn create_raw_demuxer<'a>(dmxcr: &dyn RawDemuxerCreator, br: &'a mut dyn ByteIO) -> DemuxerResult<RawDemuxer<'a>> {
     let mut dmx = dmxcr.new_demuxer(br);
     let mut strmgr = StreamManager::new();
     let mut seek_idx = SeekIndex::new();
@@ -635,7 +635,7 @@ pub fn create_raw_demuxer<'a>(dmxcr: &dyn RawDemuxerCreator, br: &'a mut ByteRea
 }
 
 /// Creates raw data demuxer for a provided bytestream with options applied right after its creation.
-pub fn create_raw_demuxer_with_options<'a>(dmxcr: &dyn RawDemuxerCreator, br: &'a mut ByteReader<'a>, opts: &[NAOption]) -> DemuxerResult<RawDemuxer<'a>> {
+pub fn create_raw_demuxer_with_options<'a>(dmxcr: &dyn RawDemuxerCreator, br: &'a mut dyn ByteIO, opts: &[NAOption]) -> DemuxerResult<RawDemuxer<'a>> {
     let mut dmx = dmxcr.new_demuxer(br);
     dmx.set_options(opts);
     let mut strmgr = StreamManager::new();
index ec62e9f24125e7b834a7805eb1e2fd3d069f1f88..e127a0fb55d224d75e35de78933d54379e24695e 100644 (file)
@@ -25,81 +25,6 @@ pub enum ByteIOError {
 /// A specialised `Result` type for bytestream operations.
 pub type ByteIOResult<T> = Result<T, ByteIOError>;
 
-/// Common trait for bytestream operations.
-pub trait ByteIO {
-    /// Reads data into provided buffer. Fails if it cannot fill whole buffer.
-    fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<()>;
-    /// Reads data into provided buffer. Partial read is treated as success.
-    fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
-    /// Reads data into provided buffer but does not advance read position.
-    fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
-    /// Reads single byte from the stream.
-    fn read_byte(&mut self) -> ByteIOResult<u8>;
-    /// Returns the next byte value in the stream without advancing read position.
-    fn peek_byte(&mut self) -> ByteIOResult<u8>;
-    /// Writes buffer to the stream.
-    fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()>;
-    /// Returns current read or write position.
-    fn tell(&mut self) -> u64;
-    /// Seeks to the provided position.
-    fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64>;
-    /// Tells whether this is end of stream.
-    fn is_eof(&self) -> bool;
-    /// Reports whether stream is seekable or not.
-    fn is_seekable(&mut self) -> bool;
-    /// Returns stream size or -1 if it is not known.
-    fn size(&mut self) -> i64;
-    /// Flushes output if possible.
-    fn flush(&mut self) -> ByteIOResult<()>;
-}
-
-/// High-level bytestream reader.
-///
-/// 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.
-///
-/// # Examples
-///
-/// ````
-/// use nihav_core::io::byteio::{MemoryReader,ByteReader};
-/// # use nihav_core::io::byteio::ByteIOResult;
-///
-/// # fn foo() -> ByteIOResult<()> {
-/// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
-/// let mut mr = MemoryReader::new_read(&memory);
-/// let mut br = ByteReader::new(&mut mr);
-/// let val = br.read_u16be()?; // read 16-bit big-endian integer, should be 42
-/// let val = br.read_u16le()?; // read 16-bit little-endian integer, should be 42 as well
-/// # Ok(())
-/// # }
-/// ````
-///
-/// [`ByteIO`]: ./trait.ByteIO.html
-/// [`MemoryReader`]: ./struct.MemoryReader.html
-#[allow(dead_code)]
-pub struct ByteReader<'a> {
-    io: &'a mut dyn ByteIO,
-}
-
-/// Bytestream reader from memory.
-pub struct MemoryReader<'a> {
-    buf:      &'a [u8],
-    pos:      usize,
-}
-
-/// Bytestream reader from anything implementing `std::io::Read` and `std::io::Seek`.
-pub struct FileReader<T: Read+Seek> {
-    file:     Box<T>,
-    eof:      bool,
-}
-
-/// Bytestream reader from anything implementing `std::io::Read` and `std::io::Seek` that operates only on a part of the input.
-pub struct BoundedFileReader<T: Read+Seek> {
-    file:     Box<T>,
-    start:    u64,
-    end:      Option<u64>,
-    eof:      bool,
-}
-
 macro_rules! read_int {
     ($s: ident, $inttype: ty, $size: expr, $which: ident) => ({
         unsafe {
@@ -120,361 +45,462 @@ macro_rules! peek_int {
     })
 }
 
-macro_rules! read_int_func {
-    ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
-/// Reads integer of certain size and endianness.
-        pub fn $s(src: &[u8]) -> ByteIOResult<$inttype> {
-            if src.len() < $size { return Err(ByteIOError::ReadError); }
-            unsafe {
-                let mut buf: $inttype = 0;
-                ptr::copy_nonoverlapping(src.as_ptr(), &mut buf as *mut $inttype as *mut u8, std::mem::size_of::<$inttype>());
-                Ok(buf.$which())
-            }
-        }
-    }
-}
-
-read_int_func!(read_u16be, u16, 2, to_be);
-read_int_func!(read_u16le, u16, 2, to_le);
-read_int_func!(read_u32be, u32, 4, to_be);
-read_int_func!(read_u32le, u32, 4, to_le);
-read_int_func!(read_u64be, u64, 8, to_be);
-read_int_func!(read_u64le, u64, 8, to_le);
-
-/// Reads 24-bit big-endian integer.
+/// Common trait for bytestream operations.
 ///
-/// # Example
+/// User is supposed to create some reader/writer implementing this trait e.g. [`MemoryReader`] or [`MemoryWriter`] and use extended functions for reading or writing e.g. various integer types.
+///
+/// # Examples
 ///
+/// Read two 16-bit integers of different endianness:
 /// ````
-/// use nihav_core::io::byteio::read_u24be;
+/// use nihav_core::io::byteio::{ByteIO,MemoryReader};
 /// # use nihav_core::io::byteio::ByteIOResult;
 ///
 /// # fn foo() -> ByteIOResult<()> {
-/// let src: [u8; 3] = [ 1, 2, 3];
-/// let value = read_u24be(&src)?; // should return 0x010203
+/// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
+/// let mut br = MemoryReader::new_read(&memory);
+/// let val = br.read_u16be()?; // read 16-bit big-endian integer, should be 42
+/// let val = br.read_u16le()?; // read 16-bit little-endian integer, should be 42 as well
 /// # Ok(())
 /// # }
 /// ````
-pub fn read_u24be(src: &[u8]) -> ByteIOResult<u32> {
-    if src.len() < 3 { return Err(ByteIOError::ReadError); }
-    Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
-}
-/// Reads 24-bit little-endian integer.
-pub fn read_u24le(src: &[u8]) -> ByteIOResult<u32> {
-    if src.len() < 3 { return Err(ByteIOError::ReadError); }
-    Ok((u32::from(src[2]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[0]))
-}
-/// Reads 32-bit big-endian floating point number.
-pub fn read_f32be(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32be(src)?)) }
-/// Reads 32-bit little-endian floating point number.
-pub fn read_f32le(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32le(src)?)) }
-/// Reads 64-bit big-endian floating point number.
-pub fn read_f64be(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64be(src)?)) }
-/// Reads 64-bit little-endian floating point number.
-pub fn read_f64le(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64le(src)?)) }
-
-macro_rules! write_int_func {
-    ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
-/// Writes integer of certain size and endianness into byte buffer.
-        pub fn $s(dst: &mut [u8], val: $inttype) -> ByteIOResult<()> {
-            if dst.len() < $size { return Err(ByteIOError::WriteError); }
-            unsafe {
-                let val = val.$which();
-                ptr::copy_nonoverlapping(&val as *const $inttype as *const u8, dst.as_mut_ptr(), std::mem::size_of::<$inttype>());
-            }
-            Ok(())
-        }
-    }
-}
-
-write_int_func!(write_u16be, u16, 2, to_be);
-write_int_func!(write_u16le, u16, 2, to_le);
-write_int_func!(write_u32be, u32, 4, to_be);
-write_int_func!(write_u32le, u32, 4, to_le);
-write_int_func!(write_u64be, u64, 8, to_be);
-write_int_func!(write_u64le, u64, 8, to_le);
-
-/// Writes 24-bit big-endian integer to the provided buffer.
-///
-/// # Example
 ///
+/// Write two 16-bit integers of different endianness:
 /// ````
-/// use nihav_core::io::byteio::write_u24be;
+/// use nihav_core::io::byteio::{ByteIO,MemoryWriter};
 /// # use nihav_core::io::byteio::ByteIOResult;
 ///
 /// # fn foo() -> ByteIOResult<()> {
-/// let mut dst = [0u8; 3];
-/// write_u24be(&mut dst, 0x010203)?;
-/// // dst should contain [ 1, 2, 3] now
+/// let mut memory = [0u8; 4];
+/// let mut bw = MemoryWriter::new_write(&mut memory);
+/// let val = bw.write_u16be(42)?; // memory should be [ 0, 42, 0, 0 ]
+/// let val = bw.write_u16le(42)?; // memory should be [ 0, 42, 42, 0 ]
 /// # Ok(())
 /// # }
 /// ````
-#[allow(clippy::identity_op)]
-pub fn write_u24be(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
-    if dst.len() < 3 { return Err(ByteIOError::WriteError); }
-    dst[0] = (val >> 16) as u8;
-    dst[1] = (val >>  8) as u8;
-    dst[2] = (val >>  0) as u8;
-    Ok(())
-}
-/// Writes 24-bit little-endian integer to the provided buffer.
-#[allow(clippy::identity_op)]
-pub fn write_u24le(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
-    if dst.len() < 3 { return Err(ByteIOError::WriteError); }
-    dst[0] = (val >>  0) as u8;
-    dst[1] = (val >>  8) as u8;
-    dst[2] = (val >> 16) as u8;
-    Ok(())
-}
-/// Writes 32-bit big-endian floating point number to the provided buffer.
-pub fn write_f32be(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32be(dst, val.to_bits()) }
-/// Writes 32-bit little-endian floating point number to the provided buffer.
-pub fn write_f32le(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32le(dst, val.to_bits()) }
-/// Writes 64-bit big-endian floating point number to the provided buffer.
-pub fn write_f64be(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64be(dst, val.to_bits()) }
-/// Writes 64-bit little-endian floating point number to the provided buffer.
-pub fn write_f64le(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64le(dst, val.to_bits()) }
-
-impl<'a> ByteReader<'a> {
-    /// Constructs a new instance of bytestream reader.
-    ///
-    /// # Examples
-    ///
-    /// ````
-    /// use nihav_core::io::byteio::{MemoryReader,ByteReader};
-    /// # use nihav_core::io::byteio::ByteIOResult;
-    ///
-    /// # fn foo() -> ByteIOResult<()> {
-    /// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
-    /// let mut mr = MemoryReader::new_read(&memory);
-    /// let mut br = ByteReader::new(&mut mr);
-    /// # Ok(())
-    /// # }
-    /// ````
-    pub fn new(io: &'a mut dyn ByteIO) -> Self { ByteReader { io } }
-
-    /// Reads data into provided buffer. Partial read is treated as failure.
-    pub fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<()> {
-        self.io.read_buf(buf)
-    }
-
-    /// Allocates additional space in vector and reads data there. Partial read is treated as failure.
-    pub fn read_extend(&mut self, buf: &mut Vec<u8>, add_size: usize) -> ByteIOResult<()> {
-        let cur_size = buf.len();
-        buf.resize(cur_size + add_size, 0);
-        self.io.read_buf(&mut buf[cur_size..])
-    }
-
+///
+/// [`ByteIO`]: ./trait.ByteIO.html
+/// [`MemoryReader`]: ./struct.MemoryReader.html
+/// [`MemoryWriter`]: ./struct.MemoryWriter.html
+pub trait ByteIO {
+    /// Reads data into provided buffer. Fails if it cannot fill whole buffer.
+    fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<()>;
     /// Reads data into provided buffer. Partial read is treated as success.
-    pub fn read_buf_some(&mut self, buf: &mut [u8])  -> ByteIOResult<usize> {
-        self.io.read_buf_some(buf)
-    }
-
+    fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
     /// Reads data into provided buffer but does not advance read position.
-    pub fn peek_buf(&mut self, buf: &mut [u8])  -> ByteIOResult<usize> {
-        self.io.peek_buf(buf)
-    }
-
+    fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
     /// Reads single byte from the stream.
-    pub fn read_byte(&mut self) -> ByteIOResult<u8> {
-        self.io.read_byte()
-    }
-
+    fn read_byte(&mut self) -> ByteIOResult<u8>;
     /// Returns the next byte value in the stream without advancing read position.
-    pub fn peek_byte(&mut self) -> ByteIOResult<u8> {
-        self.io.peek_byte()
+    fn peek_byte(&mut self) -> ByteIOResult<u8>;
+    /// Writes buffer to the stream.
+    fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()>;
+    /// Returns current read or write position.
+    fn tell(&mut self) -> u64;
+    /// Seeks to the provided position.
+    fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64>;
+    /// Tells whether this is end of stream.
+    fn is_eof(&self) -> bool;
+    /// Reports whether stream is seekable or not.
+    fn is_seekable(&mut self) -> bool;
+    /// Returns stream size or -1 if it is not known.
+    fn size(&mut self) -> i64;
+    /// Flushes output if possible.
+    fn flush(&mut self) -> ByteIOResult<()>;
+
+    /// Allocates additional space in vector and reads data there. Partial read is treated as failure.
+    fn read_extend(&mut self, buf: &mut Vec<u8>, add_size: usize) -> ByteIOResult<()> {
+        let cur_size = buf.len();
+        buf.resize(cur_size + add_size, 0);
+        self.read_buf(&mut buf[cur_size..])
     }
 
     /// Reads four-byte array from the stream.
-    pub fn read_tag(&mut self)  -> ByteIOResult<[u8; 4]> {
+    fn read_tag(&mut self)  -> ByteIOResult<[u8; 4]> {
         let mut buf = [0u8; 4];
-        self.io.read_buf(&mut buf)?;
+        self.read_buf(&mut buf)?;
         Ok(buf)
     }
 
     /// Reads four-byte array from the stream without advancing read position.
-    pub fn peek_tag(&mut self)  -> ByteIOResult<[u8; 4]> {
+    fn peek_tag(&mut self)  -> ByteIOResult<[u8; 4]> {
         let mut buf = [0u8; 4];
-        self.io.peek_buf(&mut buf)?;
+        self.peek_buf(&mut buf)?;
         Ok(buf)
     }
 
     /// Reads 16-bit big-endian integer from the stream.
-    pub fn read_u16be(&mut self) -> ByteIOResult<u16> {
+    fn read_u16be(&mut self) -> ByteIOResult<u16> {
         read_int!(self, u16, 2, to_be)
     }
 
     /// Reads 16-bit big-endian integer from the stream without advancing read position.
-    pub fn peek_u16be(&mut self) -> ByteIOResult<u16> {
+    fn peek_u16be(&mut self) -> ByteIOResult<u16> {
         peek_int!(self, u16, 2, to_be)
     }
 
     /// Reads 24-bit big-endian integer from the stream.
-    pub fn read_u24be(&mut self) -> ByteIOResult<u32> {
+    fn read_u24be(&mut self) -> ByteIOResult<u32> {
         let p16 = self.read_u16be()?;
         let p8 = self.read_byte()?;
         Ok((u32::from(p16) << 8) | u32::from(p8))
     }
 
     /// Reads 24-bit big-endian integer from the stream without advancing read position.
-    pub fn peek_u24be(&mut self) -> ByteIOResult<u32> {
+    fn peek_u24be(&mut self) -> ByteIOResult<u32> {
         let mut src: [u8; 3] = [0; 3];
         self.peek_buf(&mut src)?;
         Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
     }
 
     /// Reads 32-bit big-endian integer from the stream.
-    pub fn read_u32be(&mut self) -> ByteIOResult<u32> {
+    fn read_u32be(&mut self) -> ByteIOResult<u32> {
         read_int!(self, u32, 4, to_be)
     }
 
     /// Reads 32-bit big-endian integer from the stream without advancing read position.
-    pub fn peek_u32be(&mut self) -> ByteIOResult<u32> {
+    fn peek_u32be(&mut self) -> ByteIOResult<u32> {
         peek_int!(self, u32, 4, to_be)
     }
 
     /// Reads 64-bit big-endian integer from the stream.
-    pub fn read_u64be(&mut self) -> ByteIOResult<u64> {
+    fn read_u64be(&mut self) -> ByteIOResult<u64> {
         read_int!(self, u64, 8, to_be)
     }
 
     /// Reads 64-bit big-endian integer from the stream without advancing read position.
-    pub fn peek_u64be(&mut self) -> ByteIOResult<u64> {
+    fn peek_u64be(&mut self) -> ByteIOResult<u64> {
         peek_int!(self, u64, 8, to_be)
     }
 
     /// Reads 32-bit big-endian floating point number from the stream.
-    pub fn read_f32be(&mut self) -> ByteIOResult<f32> {
+    fn read_f32be(&mut self) -> ByteIOResult<f32> {
         Ok(f32::from_bits(self.read_u32be()?))
     }
 
     /// Reads 32-bit big-endian floating point number from the stream without advancing read position.
-    pub fn peek_f32be(&mut self) -> ByteIOResult<f32> {
+    fn peek_f32be(&mut self) -> ByteIOResult<f32> {
         Ok(f32::from_bits(self.peek_u32be()?))
     }
 
     /// Reads 64-bit big-endian floating point number from the stream.
-    pub fn read_f64be(&mut self) -> ByteIOResult<f64> {
+    fn read_f64be(&mut self) -> ByteIOResult<f64> {
         Ok(f64::from_bits(self.read_u64be()?))
     }
 
     /// Reads 64-bit big-endian floating point number from the stream without advancing read position.
-    pub fn peek_f64be(&mut self) -> ByteIOResult<f64> {
+    fn peek_f64be(&mut self) -> ByteIOResult<f64> {
         Ok(f64::from_bits(self.peek_u64be()?))
     }
 
     /// Reads 16-bit little-endian integer from the stream.
-    pub fn read_u16le(&mut self) -> ByteIOResult<u16> {
+    fn read_u16le(&mut self) -> ByteIOResult<u16> {
         read_int!(self, u16, 2, to_le)
     }
 
     /// Reads 16-bit little-endian integer from the stream without advancing read position.
-    pub fn peek_u16le(&mut self) -> ByteIOResult<u16> {
+    fn peek_u16le(&mut self) -> ByteIOResult<u16> {
         peek_int!(self, u16, 2, to_le)
     }
 
     /// Reads 24-bit little-endian integer from the stream.
-    pub fn read_u24le(&mut self) -> ByteIOResult<u32> {
+    fn read_u24le(&mut self) -> ByteIOResult<u32> {
         let p8 = self.read_byte()?;
         let p16 = self.read_u16le()?;
         Ok((u32::from(p16) << 8) | u32::from(p8))
     }
 
     /// Reads 24-bit little-endian integer from the stream without advancing read position.
-    pub fn peek_u24le(&mut self) -> ByteIOResult<u32> {
+    fn peek_u24le(&mut self) -> ByteIOResult<u32> {
         let mut src: [u8; 3] = [0; 3];
         self.peek_buf(&mut src)?;
         Ok(u32::from(src[0]) | (u32::from(src[1]) << 8) | (u32::from(src[2]) << 16))
     }
 
     /// Reads 32-bit little-endian integer from the stream.
-    pub fn read_u32le(&mut self) -> ByteIOResult<u32> {
+    fn read_u32le(&mut self) -> ByteIOResult<u32> {
         read_int!(self, u32, 4, to_le)
     }
 
     /// Reads 32-bit little-endian integer from the stream without advancing read position.
-    pub fn peek_u32le(&mut self) -> ByteIOResult<u32> {
+    fn peek_u32le(&mut self) -> ByteIOResult<u32> {
         peek_int!(self, u32, 4, to_le)
     }
 
     /// Reads 64-bit little-endian integer from the stream.
-    pub fn read_u64le(&mut self) -> ByteIOResult<u64> {
+    fn read_u64le(&mut self) -> ByteIOResult<u64> {
         read_int!(self, u64, 8, to_le)
     }
 
     /// Reads 64-bit little-endian integer from the stream without advancing read position.
-    pub fn peek_u64le(&mut self) -> ByteIOResult<u64> {
+    fn peek_u64le(&mut self) -> ByteIOResult<u64> {
         peek_int!(self, u64, 8, to_le)
     }
 
     /// Reads 32-bit little-endian floating point number from the stream.
-    pub fn read_f32le(&mut self) -> ByteIOResult<f32> {
+    fn read_f32le(&mut self) -> ByteIOResult<f32> {
         Ok(f32::from_bits(self.read_u32le()?))
     }
 
     /// Reads 32-bit little-endian floating point number from the stream without advancing read position.
-    pub fn peek_f32le(&mut self) -> ByteIOResult<f32> {
+    fn peek_f32le(&mut self) -> ByteIOResult<f32> {
         Ok(f32::from_bits(self.peek_u32le()?))
     }
 
     /// Reads 64-bit little-endian floating point number from the stream.
-    pub fn read_f64le(&mut self) -> ByteIOResult<f64> {
+    fn read_f64le(&mut self) -> ByteIOResult<f64> {
         Ok(f64::from_bits(self.read_u64le()?))
     }
 
     /// Reads 64-bit little-endian floating point number from the stream without advancing read position.
-    pub fn peek_f64le(&mut self) -> ByteIOResult<f64> {
+    fn peek_f64le(&mut self) -> ByteIOResult<f64> {
         Ok(f64::from_bits(self.peek_u64le()?))
     }
 
     /// Skips requested number of bytes.
-    pub fn read_skip(&mut self, len: usize) -> ByteIOResult<()> {
-        if self.io.is_seekable() {
-            self.io.seek(SeekFrom::Current(len as i64))?;
+    fn read_skip(&mut self, len: usize) -> ByteIOResult<()> {
+        if self.is_seekable() {
+            self.seek(SeekFrom::Current(len as i64))?;
         } else {
             let mut ssize = len;
             let mut buf : [u8; 16] = [0; 16];
             let bref = &mut buf;
             while ssize > bref.len() {
-                self.io.read_buf(bref)?;
+                self.read_buf(bref)?;
                 ssize -= bref.len();
             }
             while ssize > 0 {
-                self.io.read_byte()?;
+                self.read_byte()?;
                 ssize -= 1;
             }
         }
         Ok(())
     }
 
-    /// Returns current read position.
-    pub fn tell(&mut self) -> u64 {
-        self.io.tell()
+    /// Reports number of bytes left in the stream.
+    fn left(&mut self) -> i64 {
+        let size = self.size();
+        if size == -1 { return -1; }
+        size - (self.tell() as i64)
     }
 
-    /// Seeks to the provided position.
-    pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
-        self.io.seek(pos)
+    /// Writes single byte to the output.
+    fn write_byte(&mut self, val: u8) -> ByteIOResult<()> {
+        let buf: [u8; 1] = [val];
+        self.write_buf(&buf)
     }
 
-    /// Tells whether this is end of stream.
-    pub fn is_eof(&self) -> bool {
-        self.io.is_eof()
+    /// Writes 16-bit big-endian integer to the output.
+    fn write_u16be(&mut self, val: u16) -> ByteIOResult<()> {
+        let buf: [u8; 2] = [((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
+        self.write_buf(&buf)
     }
 
-    /// Returns stream size or -1 if it is not known.
-    pub fn size(&mut self) -> i64 {
-        self.io.size()
+    /// Writes 16-bit little-endian integer to the output.
+    fn write_u16le(&mut self, val: u16) -> ByteIOResult<()> {
+        let buf: [u8; 2] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8];
+        self.write_buf(&buf)
     }
 
-    /// Reports number of bytes left in the stream.
-    pub fn left(&mut self) -> i64 {
-        let size = self.io.size();
-        if size == -1 { return -1; }
-        size - (self.io.tell() as i64)
+    /// Writes 24-bit big-endian integer to the output.
+    fn write_u24be(&mut self, val: u32) -> ByteIOResult<()> {
+        let buf: [u8; 3] = [((val >> 16) & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
+        self.write_buf(&buf)
+    }
+
+    /// Writes 24-bit little-endian integer to the output.
+    fn write_u24le(&mut self, val: u32) -> ByteIOResult<()> {
+        let buf: [u8; 3] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, ((val >> 16) & 0xFF) as u8];
+        self.write_buf(&buf)
+    }
+
+    /// Writes 32-bit big-endian integer to the output.
+    fn write_u32be(&mut self, val: u32) -> ByteIOResult<()> {
+        self.write_u16be(((val >> 16) & 0xFFFF) as u16)?;
+        self.write_u16be((val & 0xFFFF) as u16)
+    }
+
+    /// Writes 32-bit little-endian integer to the output.
+    fn write_u32le(&mut self, val: u32) -> ByteIOResult<()> {
+        self.write_u16le((val & 0xFFFF) as u16)?;
+        self.write_u16le(((val >> 16) & 0xFFFF) as u16)
+    }
+
+    /// Writes 64-bit big-endian integer to the output.
+    fn write_u64be(&mut self, val: u64) -> ByteIOResult<()> {
+        self.write_u32be((val >> 32) as u32)?;
+        self.write_u32be(val as u32)
+    }
+
+    /// Writes 64-bit little-endian integer to the output.
+    fn write_u64le(&mut self, val: u64) -> ByteIOResult<()> {
+        self.write_u32le(val as u32)?;
+        self.write_u32le((val >> 32) as u32)
+    }
+
+    /// Writes 32-bit big-endian floating point number to the output.
+    fn write_f32be(&mut self, val: f32) -> ByteIOResult<()> {
+        self.write_u32be(val.to_bits())
+    }
+
+    /// Writes 32-bit little-endian floating point number to the output.
+    fn write_f32le(&mut self, val: f32) -> ByteIOResult<()> {
+        self.write_u32le(val.to_bits())
+    }
+
+    /// Writes 64-bit big-endian floating point number to the output.
+    fn write_f64be(&mut self, val: f64) -> ByteIOResult<()> {
+        self.write_u64be(val.to_bits())
+    }
+
+    /// Writes 64-bit little-endian floating point number to the output.
+    fn write_f64le(&mut self, val: f64) -> ByteIOResult<()> {
+        self.write_u64le(val.to_bits())
+    }
+
+    /// Reports the amount of bytes the writer can still write (-1 if unknown).
+    fn size_left(&mut self) -> i64 {
+        let sz = self.size();
+        if sz == -1 { return -1; }
+        sz - (self.tell() as i64)
+    }
+}
+
+/// Bytestream reader from memory.
+pub struct MemoryReader<'a> {
+    buf:      &'a [u8],
+    pos:      usize,
+}
+
+/// Bytestream reader from anything implementing `std::io::Read` and `std::io::Seek`.
+pub struct FileReader<T: Read+Seek> {
+    file:     Box<T>,
+    eof:      bool,
+}
+
+/// Bytestream reader from anything implementing `std::io::Read` and `std::io::Seek` that operates only on a part of the input.
+pub struct BoundedFileReader<T: Read+Seek> {
+    file:     Box<T>,
+    start:    u64,
+    end:      Option<u64>,
+    eof:      bool,
+}
+
+macro_rules! read_int_func {
+    ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
+/// Reads integer of certain size and endianness.
+        pub fn $s(src: &[u8]) -> ByteIOResult<$inttype> {
+            if src.len() < $size { return Err(ByteIOError::ReadError); }
+            unsafe {
+                let mut buf: $inttype = 0;
+                ptr::copy_nonoverlapping(src.as_ptr(), &mut buf as *mut $inttype as *mut u8, std::mem::size_of::<$inttype>());
+                Ok(buf.$which())
+            }
+        }
     }
 }
 
+read_int_func!(read_u16be, u16, 2, to_be);
+read_int_func!(read_u16le, u16, 2, to_le);
+read_int_func!(read_u32be, u32, 4, to_be);
+read_int_func!(read_u32le, u32, 4, to_le);
+read_int_func!(read_u64be, u64, 8, to_be);
+read_int_func!(read_u64le, u64, 8, to_le);
+
+/// Reads 24-bit big-endian integer.
+///
+/// # Example
+///
+/// ````
+/// use nihav_core::io::byteio::read_u24be;
+/// # use nihav_core::io::byteio::ByteIOResult;
+///
+/// # fn foo() -> ByteIOResult<()> {
+/// let src: [u8; 3] = [ 1, 2, 3];
+/// let value = read_u24be(&src)?; // should return 0x010203
+/// # Ok(())
+/// # }
+/// ````
+pub fn read_u24be(src: &[u8]) -> ByteIOResult<u32> {
+    if src.len() < 3 { return Err(ByteIOError::ReadError); }
+    Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
+}
+/// Reads 24-bit little-endian integer.
+pub fn read_u24le(src: &[u8]) -> ByteIOResult<u32> {
+    if src.len() < 3 { return Err(ByteIOError::ReadError); }
+    Ok((u32::from(src[2]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[0]))
+}
+/// Reads 32-bit big-endian floating point number.
+pub fn read_f32be(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32be(src)?)) }
+/// Reads 32-bit little-endian floating point number.
+pub fn read_f32le(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32le(src)?)) }
+/// Reads 64-bit big-endian floating point number.
+pub fn read_f64be(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64be(src)?)) }
+/// Reads 64-bit little-endian floating point number.
+pub fn read_f64le(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64le(src)?)) }
+
+macro_rules! write_int_func {
+    ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
+/// Writes integer of certain size and endianness into byte buffer.
+        pub fn $s(dst: &mut [u8], val: $inttype) -> ByteIOResult<()> {
+            if dst.len() < $size { return Err(ByteIOError::WriteError); }
+            unsafe {
+                let val = val.$which();
+                ptr::copy_nonoverlapping(&val as *const $inttype as *const u8, dst.as_mut_ptr(), std::mem::size_of::<$inttype>());
+            }
+            Ok(())
+        }
+    }
+}
+
+write_int_func!(write_u16be, u16, 2, to_be);
+write_int_func!(write_u16le, u16, 2, to_le);
+write_int_func!(write_u32be, u32, 4, to_be);
+write_int_func!(write_u32le, u32, 4, to_le);
+write_int_func!(write_u64be, u64, 8, to_be);
+write_int_func!(write_u64le, u64, 8, to_le);
+
+/// Writes 24-bit big-endian integer to the provided buffer.
+///
+/// # Example
+///
+/// ````
+/// use nihav_core::io::byteio::write_u24be;
+/// # use nihav_core::io::byteio::ByteIOResult;
+///
+/// # fn foo() -> ByteIOResult<()> {
+/// let mut dst = [0u8; 3];
+/// write_u24be(&mut dst, 0x010203)?;
+/// // dst should contain [ 1, 2, 3] now
+/// # Ok(())
+/// # }
+/// ````
+#[allow(clippy::identity_op)]
+pub fn write_u24be(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
+    if dst.len() < 3 { return Err(ByteIOError::WriteError); }
+    dst[0] = (val >> 16) as u8;
+    dst[1] = (val >>  8) as u8;
+    dst[2] = (val >>  0) as u8;
+    Ok(())
+}
+/// Writes 24-bit little-endian integer to the provided buffer.
+#[allow(clippy::identity_op)]
+pub fn write_u24le(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
+    if dst.len() < 3 { return Err(ByteIOError::WriteError); }
+    dst[0] = (val >>  0) as u8;
+    dst[1] = (val >>  8) as u8;
+    dst[2] = (val >> 16) as u8;
+    Ok(())
+}
+/// Writes 32-bit big-endian floating point number to the provided buffer.
+pub fn write_f32be(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32be(dst, val.to_bits()) }
+/// Writes 32-bit little-endian floating point number to the provided buffer.
+pub fn write_f32le(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32le(dst, val.to_bits()) }
+/// Writes 64-bit big-endian floating point number to the provided buffer.
+pub fn write_f64be(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64be(dst, val.to_bits()) }
+/// Writes 64-bit little-endian floating point number to the provided buffer.
+pub fn write_f64le(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64le(dst, val.to_bits()) }
+
 impl<'a> MemoryReader<'a> {
     /// Constructs a new instance of `MemoryReader`.
     pub fn new_read(buf: &'a [u8]) -> Self {
@@ -840,33 +866,6 @@ impl<T: Read+Seek> ByteIO for BoundedFileReader<T> {
 }
 
 
-/// High-level bytestream writer.
-///
-/// 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.
-///
-/// # Examples
-///
-/// ````
-/// use nihav_core::io::byteio::{MemoryWriter,ByteWriter};
-/// # use nihav_core::io::byteio::ByteIOResult;
-///
-/// # fn foo() -> ByteIOResult<()> {
-/// let mut memory = [0u8; 4];
-/// let mut mw = MemoryWriter::new_write(&mut memory);
-/// let mut bw = ByteWriter::new(&mut mw);
-/// let val = bw.write_u16be(42)?; // memory should be [ 0, 42, 0, 0 ]
-/// let val = bw.write_u16le(42)?; // memory should be [ 0, 42, 42, 0 ]
-/// # Ok(())
-/// # }
-/// ````
-///
-/// [`ByteIO`]: ./trait.ByteIO.html
-/// [`MemoryWriter`]: ./struct.MemoryWriter.html
-#[allow(dead_code)]
-pub struct ByteWriter<'a> {
-    io: &'a mut dyn ByteIO,
-}
-
 /// Bytestream writer to memory.
 pub struct MemoryWriter<'a> {
     buf:      &'a mut [u8],
@@ -888,112 +887,6 @@ pub struct GrowableMemoryWriter<'a> {
     pos:    usize,
 }
 
-impl<'a> ByteWriter<'a> {
-    /// Constructs a new instance of `ByteWriter`.
-    pub fn new(io: &'a mut dyn ByteIO) -> Self { ByteWriter { io } }
-
-    /// Writes byte array to the output.
-    pub fn write_buf(&mut self, buf: &[u8])  -> ByteIOResult<()> {
-        self.io.write_buf(buf)
-    }
-
-    /// Writes single byte to the output.
-    pub fn write_byte(&mut self, val: u8) -> ByteIOResult<()> {
-        let buf: [u8; 1] = [val];
-        self.io.write_buf(&buf)
-    }
-
-    /// Writes 16-bit big-endian integer to the output.
-    pub fn write_u16be(&mut self, val: u16) -> ByteIOResult<()> {
-        let buf: [u8; 2] = [((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
-        self.io.write_buf(&buf)
-    }
-
-    /// Writes 16-bit little-endian integer to the output.
-    pub fn write_u16le(&mut self, val: u16) -> ByteIOResult<()> {
-        let buf: [u8; 2] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8];
-        self.io.write_buf(&buf)
-    }
-
-    /// Writes 24-bit big-endian integer to the output.
-    pub fn write_u24be(&mut self, val: u32) -> ByteIOResult<()> {
-        let buf: [u8; 3] = [((val >> 16) & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
-        self.write_buf(&buf)
-    }
-
-    /// Writes 24-bit little-endian integer to the output.
-    pub fn write_u24le(&mut self, val: u32) -> ByteIOResult<()> {
-        let buf: [u8; 3] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, ((val >> 16) & 0xFF) as u8];
-        self.write_buf(&buf)
-    }
-
-    /// Writes 32-bit big-endian integer to the output.
-    pub fn write_u32be(&mut self, val: u32) -> ByteIOResult<()> {
-        self.write_u16be(((val >> 16) & 0xFFFF) as u16)?;
-        self.write_u16be((val & 0xFFFF) as u16)
-    }
-
-    /// Writes 32-bit little-endian integer to the output.
-    pub fn write_u32le(&mut self, val: u32) -> ByteIOResult<()> {
-        self.write_u16le((val & 0xFFFF) as u16)?;
-        self.write_u16le(((val >> 16) & 0xFFFF) as u16)
-    }
-
-    /// Writes 64-bit big-endian integer to the output.
-    pub fn write_u64be(&mut self, val: u64) -> ByteIOResult<()> {
-        self.write_u32be((val >> 32) as u32)?;
-        self.write_u32be(val as u32)
-    }
-
-    /// Writes 64-bit little-endian integer to the output.
-    pub fn write_u64le(&mut self, val: u64) -> ByteIOResult<()> {
-        self.write_u32le(val as u32)?;
-        self.write_u32le((val >> 32) as u32)
-    }
-
-    /// Writes 32-bit big-endian floating point number to the output.
-    pub fn write_f32be(&mut self, val: f32) -> ByteIOResult<()> {
-        self.write_u32be(val.to_bits())
-    }
-
-    /// Writes 32-bit little-endian floating point number to the output.
-    pub fn write_f32le(&mut self, val: f32) -> ByteIOResult<()> {
-        self.write_u32le(val.to_bits())
-    }
-
-    /// Writes 64-bit big-endian floating point number to the output.
-    pub fn write_f64be(&mut self, val: f64) -> ByteIOResult<()> {
-        self.write_u64be(val.to_bits())
-    }
-
-    /// Writes 64-bit little-endian floating point number to the output.
-    pub fn write_f64le(&mut self, val: f64) -> ByteIOResult<()> {
-        self.write_u64le(val.to_bits())
-    }
-
-    /// Reports the current write position.
-    pub fn tell(&mut self) -> u64 {
-        self.io.tell()
-    }
-
-    /// Seeks to the requested position.
-    pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
-        self.io.seek(pos)
-    }
-
-    /// Reports the amount of bytes the writer can still write (-1 if unknown).
-    pub fn size_left(&mut self) -> i64 {
-        let sz = self.io.size();
-        if sz == -1 { return -1; }
-        sz - (self.tell() as i64)
-    }
-
-    /// Flushes output stream if possible.
-    pub fn flush(&mut self) -> ByteIOResult<()> {
-        self.io.flush()
-    }
-}
-
 impl<'a> MemoryWriter<'a> {
 
     /// Constructs a new instance of `MemoryWriter`.
@@ -1218,16 +1111,14 @@ mod test {
     fn test_read() {
         //const DATA : &'static [u8] = include_bytes!("../../assets/file");
         let buf: [u8; 64] = [1; 64];
-        let mut mr = MemoryReader::new_read(&buf);
-        let mut reader = ByteReader::new(&mut mr);
+        let mut reader = MemoryReader::new_read(&buf);
         assert_eq!(reader.read_byte().unwrap(),  0x01u8);
         assert_eq!(reader.read_u16le().unwrap(), 0x0101u16);
         assert_eq!(reader.read_u24le().unwrap(), 0x010101u32);
         assert_eq!(reader.read_u32le().unwrap(), 0x01010101u32);
         assert_eq!(reader.read_u64le().unwrap(), 0x0101010101010101u64);
         let mut file = File::open("assets/Misc/MaoMacha.asx").unwrap();
-        let mut fr = FileReader::new_read(&mut file);
-        let mut br2 = ByteReader::new(&mut fr);
+        let mut br2 = FileReader::new_read(&mut file);
         assert_eq!(br2.read_byte().unwrap(), 0x30);
         assert_eq!(br2.read_u24be().unwrap(), 0x26B275);
         assert_eq!(br2.read_u24le().unwrap(), 0xCF668E);
@@ -1238,8 +1129,7 @@ mod test {
     fn test_write() {
         let mut buf: [u8; 64] = [0; 64];
         {
-            let mut mw = MemoryWriter::new_write(&mut buf);
-            let mut bw = ByteWriter::new(&mut mw);
+            let mut bw = MemoryWriter::new_write(&mut buf);
             bw.write_byte(0x00).unwrap();
             bw.write_u16be(0x0102).unwrap();
             bw.write_u24be(0x030405).unwrap();
index 4df7c4a0964a904243e255a34e0a5bd896a8ef33..6ea01d8a9efc3a727960825b878d6722670f37e3 100644 (file)
@@ -164,8 +164,8 @@ impl<'a> NAOptionHandler for Muxer<'a> {
 
 /// The trait for creating muxers.
 pub trait MuxerCreator {
-    /// Creates new muxer instance that will use `ByteWriter` for output.
-    fn new_muxer<'a>(&self, bw: &'a mut ByteWriter<'a>) -> Box<dyn MuxCore<'a> + 'a>;
+    /// Creates new muxer instance that will use an object with `ByteIO` trait for output.
+    fn new_muxer<'a>(&self, bw: &'a mut dyn ByteIO) -> Box<dyn MuxCore<'a> + 'a>;
     /// Returns the name of current muxer creator (equal to the container name it can create).
     fn get_name(&self) -> &'static str;
     /// Returns muxer capabilities for the current muxer.
@@ -175,7 +175,7 @@ pub trait MuxerCreator {
 }
 
 /// Creates muxer for a provided bytestream writer.
-pub fn create_muxer<'a>(mxcr: &dyn MuxerCreator, strmgr: StreamManager, bw: &'a mut ByteWriter<'a>) -> MuxerResult<Muxer<'a>> {
+pub fn create_muxer<'a>(mxcr: &dyn MuxerCreator, strmgr: StreamManager, bw: &'a mut dyn ByteIO) -> MuxerResult<Muxer<'a>> {
     let mut mux = mxcr.new_muxer(bw);
     mux.create(&strmgr)?;
     Ok(Muxer::new(mux, strmgr))