bitbuffer 0.10.9

Reading bit sequences from a byte slice
Documentation
use std::mem::size_of;
use std::ops::BitOrAssign;

use num_traits::{Float, PrimInt};

use crate::endianness::Endianness;
use crate::num_traits::{IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
use crate::readbuffer::Data;
use crate::BitReadBuffer;
use crate::{BitError, BitRead, BitReadSized, Result};
use std::borrow::Cow;
use std::cmp::min;

/// Stream that provides an easy way to iterate trough a [`BitBuffer`]
///
/// # Examples
///
/// ```
/// use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian};
///
/// let bytes = vec![
///     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
///     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
/// ];
/// let buffer = BitReadBuffer::new(&bytes, LittleEndian);
/// let mut stream = BitReadStream::new(buffer);
/// ```
///
/// [`BitBuffer`]: struct.BitBuffer.html
#[derive(Debug)]
pub struct BitReadStream<'a, E>
where
    E: Endianness,
{
    buffer: BitReadBuffer<'a, E>,
    start_pos: usize,
    pos: usize,
}

impl<'a, E> BitReadStream<'a, E>
where
    E: Endianness,
{
    /// Create a new stream from a [`BitBuffer`]
    ///
    /// # Examples
    ///
    /// ```
    /// use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian};
    ///
    /// let bytes = vec![
    ///     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    ///     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// ];
    /// let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// let mut stream = BitReadStream::new(buffer);
    /// ```
    ///
    /// [`BitBuffer`]: struct.BitBuffer.html
    pub fn new(buffer: BitReadBuffer<'a, E>) -> Self {
        BitReadStream {
            start_pos: 0,
            pos: 0,
            buffer,
        }
    }

    /// Read a single bit from the stream as boolean
    ///
    /// # Errors
    ///
    /// - [`ReadError::NotEnoughData`]: not enough bits available in the stream
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// assert_eq!(stream.read_bool()?, true);
    /// assert_eq!(stream.read_bool()?, false);
    /// assert_eq!(stream.pos(), 2);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
    #[inline]
    pub fn read_bool(&mut self) -> Result<bool> {
        let result = self.buffer.read_bool(self.pos);
        if result.is_ok() {
            self.pos += 1;
        }
        result
    }

    #[doc(hidden)]
    #[inline]
    pub unsafe fn read_bool_unchecked(&mut self) -> bool {
        let result = self.buffer.read_bool_unchecked(self.pos);
        self.pos += 1;
        result
    }

    /// Read a sequence of bits from the stream as integer
    ///
    /// # Errors
    ///
    /// - [`ReadError::NotEnoughData`]: not enough bits available in the stream
    /// - [`ReadError::TooManyBits`]: to many bits requested for the chosen integer type
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// assert_eq!(stream.read_int::<u16>(3)?, 0b101);
    /// assert_eq!(stream.read_int::<u16>(3)?, 0b110);
    /// assert_eq!(stream.pos(), 6);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
    /// [`ReadError::TooManyBits`]: enum.ReadError.html#variant.TooManyBits
    #[inline]
    pub fn read_int<T>(&mut self, count: usize) -> Result<T>
    where
        T: PrimInt + BitOrAssign + IsSigned + UncheckedPrimitiveInt,
    {
        let result = self.buffer.read_int(self.pos, count);
        if result.is_ok() {
            self.pos += count;
        }
        result
    }

    #[doc(hidden)]
    #[inline]
    pub unsafe fn read_int_unchecked<T>(&mut self, count: usize, end: bool) -> T
    where
        T: PrimInt + BitOrAssign + IsSigned + UncheckedPrimitiveInt,
    {
        let result = self.buffer.read_int_unchecked(self.pos, count, end);
        self.pos += count;
        result
    }

    /// Read a sequence of bits from the stream as float
    ///
    /// # Errors
    ///
    /// - [`ReadError::NotEnoughData`]: not enough bits available in the stream
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// let result = stream.read_float::<f32>()?;
    /// assert_eq!(stream.pos(), 32);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
    #[inline]
    pub fn read_float<T>(&mut self) -> Result<T>
    where
        T: Float + UncheckedPrimitiveFloat,
    {
        let count = size_of::<T>() * 8;
        let result = self.buffer.read_float(self.pos);
        if result.is_ok() {
            self.pos += count;
        }
        result
    }

    #[doc(hidden)]
    #[inline]
    pub unsafe fn read_float_unchecked<T>(&mut self, end: bool) -> T
    where
        T: Float + UncheckedPrimitiveFloat,
    {
        let count = size_of::<T>() * 8;
        let result = self.buffer.read_float_unchecked(self.pos, end);
        self.pos += count;
        result
    }

    /// Read a series of bytes from the stream
    ///
    /// # Errors
    ///
    /// - [`ReadError::NotEnoughData`]: not enough bits available in the stream
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # use std::borrow::Borrow;
    /// let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// assert_eq!(stream.read_bytes(3)?.to_vec(), &[0b1011_0101, 0b0110_1010, 0b1010_1100]);
    /// assert_eq!(stream.pos(), 24);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
    #[inline]
    pub fn read_bytes(&mut self, byte_count: usize) -> Result<Cow<'a, [u8]>> {
        let count = byte_count * 8;
        let result = self.buffer.read_bytes(self.pos, byte_count);
        if result.is_ok() {
            self.pos += count;
        }
        result
    }

    #[doc(hidden)]
    #[inline]
    pub unsafe fn read_bytes_unchecked(&mut self, byte_count: usize) -> Cow<'a, [u8]> {
        let count = byte_count * 8;
        let result = self.buffer.read_bytes_unchecked(self.pos, byte_count);
        self.pos += count;
        result
    }

    /// Read a series of bytes from the stream as utf8 string
    ///
    /// You can either read a fixed number of bytes, or a dynamic length null-terminated string
    ///
    /// # Errors
    ///
    /// - [`ReadError::NotEnoughData`]: not enough bits available in the stream
    /// - [`ReadError::Utf8Error`]: the read bytes are not valid utf8
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0x48, 0x65, 0x6c, 0x6c,
    /// #     0x6f, 0x20, 0x77, 0x6f,
    /// #     0x72, 0x6c, 0x64, 0,
    /// #     0,    0,    0,    0
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// // Fixed length string
    /// stream.set_pos(0);
    /// assert_eq!(stream.read_string(Some(11))?, "Hello world".to_owned());
    /// assert_eq!(11 * 8, stream.pos());
    /// // fixed length with null padding
    /// stream.set_pos(0);
    /// assert_eq!(stream.read_string(Some(16))?, "Hello world".to_owned());
    /// assert_eq!(16 * 8, stream.pos());
    /// // null terminated
    /// stream.set_pos(0);
    /// assert_eq!(stream.read_string(None)?, "Hello world".to_owned());
    /// assert_eq!(12 * 8, stream.pos()); // 1 more for the terminating null byte
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
    /// [`ReadError::Utf8Error`]: enum.ReadError.html#variant.Utf8Error
    #[inline]
    pub fn read_string(&mut self, byte_len: Option<usize>) -> Result<Cow<'a, str>> {
        let max_length = self.bits_left() / 8;

        let result = self
            .buffer
            .read_string(self.pos, byte_len)
            .map_err(|mut err| {
                // still advance the stream on malformed utf8
                if let BitError::Utf8Error(_, len) = &mut err {
                    self.pos += match byte_len {
                        Some(len) => len * 8,
                        None => min((*len + 1) * 8, max_length * 8),
                    };

                    *len = (*len).min(max_length);
                }
                err
            })?;
        let read = match byte_len {
            Some(len) => len * 8,
            None => (result.len() + 1) * 8,
        };

        // due to how sub buffer/streams work, the result string can be longer than the current stream
        // (but not the top level buffer)
        // thus we trim the resulting string to make sure it fits in the source stream
        if read > self.bits_left() {
            // find the maximum well-formed utf8 string that fits in max_len
            let mut acc = String::with_capacity(max_length);
            for c in result.chars() {
                if acc.len() + c.len_utf8() > max_length {
                    break;
                }
                acc.push(c);
            }
            self.pos += acc.len() * 8;
            return Ok(Cow::Owned(acc));
        }
        self.pos += read;
        Ok(result)
    }

    /// Read a sequence of bits from the stream as a BitStream
    ///
    /// # Errors
    ///
    /// - [`ReadError::NotEnoughData`]: not enough bits available in the stream
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// let mut bits = stream.read_bits(3)?;
    /// assert_eq!(stream.pos(), 3);
    /// assert_eq!(bits.pos(), 0);
    /// assert_eq!(bits.bit_len(), 3);
    /// assert_eq!(stream.read_int::<u8>(3)?, 0b110);
    /// assert_eq!(bits.read_int::<u8>(3)?, 0b101);
    /// assert_eq!(true, bits.read_int::<u8>(1).is_err());
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
    pub fn read_bits(&mut self, count: usize) -> Result<Self> {
        let result = BitReadStream {
            buffer: self.buffer.get_sub_buffer(self.pos + count)?,
            start_pos: self.pos,
            pos: self.pos,
        };
        self.pos += count;
        Ok(result)
    }

    /// Skip a number of bits in the stream
    ///
    /// # Errors
    ///
    /// - [`ReadError::NotEnoughData`]: not enough bits available in the stream to skip
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// stream.skip_bits(3)?;
    /// assert_eq!(stream.pos(), 3);
    /// assert_eq!(stream.read_int::<u8>(3)?, 0b110);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
    pub fn skip_bits(&mut self, count: usize) -> Result<()> {
        if count <= self.bits_left() {
            self.pos += count;
            Ok(())
        } else {
            Err(BitError::NotEnoughData {
                requested: count,
                bits_left: self.bits_left(),
            })
        }
    }

    /// Set the position of the stream
    ///
    /// # Errors
    ///
    /// - [`ReadError::IndexOutOfBounds`]: new position is outside the bounds of the stream
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// stream.set_pos(3)?;
    /// assert_eq!(stream.pos(), 3);
    /// assert_eq!(stream.read_int::<u8>(3)?, 0b110);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`ReadError::IndexOutOfBounds`]: enum.ReadError.html#variant.IndexOutOfBounds
    pub fn set_pos(&mut self, pos: usize) -> Result<()> {
        if pos > self.bit_len() {
            return Err(BitError::IndexOutOfBounds {
                pos,
                size: self.bit_len(),
            });
        }
        self.pos = pos + self.start_pos;
        Ok(())
    }

    /// Get the length of the stream in bits
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// assert_eq!(stream.bit_len(), 64);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    pub fn bit_len(&self) -> usize {
        self.buffer.bit_len() - self.start_pos
    }

    /// Get the current position in the stream
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// assert_eq!(stream.pos(), 0);
    /// stream.skip_bits(5)?;
    /// assert_eq!(stream.pos(), 5);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    pub fn pos(&self) -> usize {
        self.pos - self.start_pos
    }

    /// Get the number of bits left in the stream
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// assert_eq!(stream.bits_left(), 64);
    /// stream.skip_bits(5)?;
    /// assert_eq!(stream.bits_left(), 59);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    pub fn bits_left(&self) -> usize {
        self.bit_len() - self.pos()
    }

    /// Read a value based on the provided type
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// let int: u8 = stream.read()?;
    /// assert_eq!(int, 0b1011_0101);
    /// let boolean: bool = stream.read()?;
    /// assert_eq!(false, boolean);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// use bitbuffer::BitRead;
    /// #
    /// #[derive(BitRead, Debug, PartialEq)]
    /// struct ComplexType {
    ///     first: u8,
    ///     #[size = 15]
    ///     second: u16,
    ///     third: bool,
    /// }
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// let data: ComplexType = stream.read()?;
    /// assert_eq!(data, ComplexType {
    ///     first: 0b1011_0101,
    ///     second: 0b010_1100_0110_1010,
    ///     third: true,
    /// });
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn read<T: BitRead<'a, E>>(&mut self) -> Result<T> {
        T::read(self)
    }

    #[doc(hidden)]
    #[inline]
    pub unsafe fn read_unchecked<T: BitRead<'a, E>>(&mut self, end: bool) -> Result<T> {
        T::read_unchecked(self, end)
    }

    /// Read a value based on the provided type and size
    ///
    /// The meaning of the size parameter differs depending on the type that is being read
    ///
    /// # Examples
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// let int: u8 = stream.read_sized(7)?;
    /// assert_eq!(int, 0b011_0101);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// ```
    /// # use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian, Result};
    /// #
    /// # fn main() -> Result<()> {
    /// # let bytes = vec![
    /// #     0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
    /// #     0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
    /// # ];
    /// # let buffer = BitReadBuffer::new(&bytes, LittleEndian);
    /// # let mut stream = BitReadStream::new(buffer);
    /// let data: Vec<u16> = stream.read_sized(3)?;
    /// assert_eq!(data, vec![0b0110_1010_1011_0101, 0b1001_1001_1010_1100, 0b1001_1001_1001_1001]);
    /// #
    /// #     Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn read_sized<T: BitReadSized<'a, E>>(&mut self, size: usize) -> Result<T> {
        T::read(self, size)
    }

    #[doc(hidden)]
    #[inline]
    pub unsafe fn read_sized_unchecked<T: BitReadSized<'a, E>>(
        &mut self,
        size: usize,
        end: bool,
    ) -> Result<T> {
        T::read_unchecked(self, size, end)
    }

    /// Check if we can read a number of bits from the stream
    pub fn check_read(&self, count: usize) -> Result<bool> {
        if self.bits_left() < count + 64 {
            if self.bits_left() < count {
                Err(BitError::NotEnoughData {
                    requested: count,
                    bits_left: self.bits_left(),
                })
            } else {
                Ok(true)
            }
        } else {
            Ok(false)
        }
    }

    /// Create an owned copy of this stream
    pub fn to_owned(&self) -> BitReadStream<'static, E> {
        match self.buffer.bytes {
            Data::Owned(_) => BitReadStream {
                // already owned, so buffer.to_owned is a cheap rc clone
                buffer: self.buffer.to_owned(),
                start_pos: self.pos,
                pos: self.pos,
            },
            Data::Borrowed(bytes) => {
                // instead of calling buffer.to_owned blindly, we only copy the bytes that this stream covers
                let byte_pos = self.start_pos / 8;
                let bit_offset = self.start_pos & 7;

                let end = self.buffer.bit_len() / 8 + 1;
                let end = min(end, self.buffer.byte_len());

                let sub_bytes = bytes[byte_pos..end].to_vec();
                let buffer = BitReadBuffer::from(sub_bytes)
                    .get_sub_buffer(self.buffer.bit_len() - self.start_pos + bit_offset)
                    .unwrap();

                BitReadStream {
                    buffer,
                    start_pos: bit_offset,
                    pos: bit_offset + (self.pos - self.start_pos),
                }
            }
        }
    }
}

impl<'a, E: Endianness> Clone for BitReadStream<'a, E> {
    fn clone(&self) -> Self {
        BitReadStream {
            buffer: self.buffer.clone(),
            start_pos: self.pos,
            pos: self.pos,
        }
    }
}

impl<'a, E: Endianness> PartialEq for BitReadStream<'a, E> {
    fn eq(&self, other: &Self) -> bool {
        // clones so we can mut
        let mut self_clone = self.clone();
        self_clone.set_pos(0).ok();
        let mut other_clone = other.clone();
        other_clone.set_pos(0).ok();

        if self_clone.bits_left() != other_clone.bits_left() {
            return false;
        }

        while self_clone.bits_left() > 32 {
            if self_clone.read::<u32>().ok() != other_clone.read().ok() {
                return false;
            }
        }

        while self_clone.bits_left() > 0 {
            if self_clone.read::<bool>().ok() != other_clone.read().ok() {
                return false;
            }
        }

        true
    }
}

impl<'a, E: Endianness> From<BitReadBuffer<'a, E>> for BitReadStream<'a, E> {
    fn from(buffer: BitReadBuffer<'a, E>) -> Self {
        BitReadStream::new(buffer)
    }
}

impl<'a, E: Endianness> From<&'a [u8]> for BitReadStream<'a, E> {
    fn from(bytes: &'a [u8]) -> Self {
        BitReadStream::new(BitReadBuffer::from(bytes))
    }
}

#[cfg(feature = "serde")]
use serde::{de, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};

#[cfg(feature = "serde")]
impl<'a, E: Endianness> Serialize for BitReadStream<'a, E> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut stream = self.clone();
        let mut data = stream.read_bytes(self.bits_left() / 8).unwrap().to_vec();
        if stream.bits_left() > 0 {
            data.push(stream.read_sized(stream.bits_left()).unwrap());
        }

        let mut s = serializer.serialize_struct("BitReadStream", 3)?;
        s.serialize_field("data", &data)?;
        s.serialize_field("bit_length", &self.bit_len())?;
        s.end()
    }
}

#[cfg(feature = "serde")]
impl<'de, E: Endianness> Deserialize<'de> for BitReadStream<'static, E> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        struct BitData {
            data: Vec<u8>,
            bit_length: usize,
        }

        let data = BitData::deserialize(deserializer)?;
        let mut buffer = BitReadBuffer::new_owned(data.data, E::endianness());
        buffer
            .truncate(data.bit_length)
            .map_err(de::Error::custom)?;
        Ok(BitReadStream::new(buffer))
    }
}

#[cfg(feature = "serde")]
#[test]
fn test_serde_roundtrip() {
    use crate::LittleEndian;

    let mut buffer = BitReadBuffer::new_owned(vec![55; 8], LittleEndian);
    buffer.truncate(61).unwrap();
    let stream = BitReadStream::new(buffer);
    assert_eq!(61, stream.bit_len());

    let json = serde_json::to_string(&stream).unwrap();

    let result: BitReadStream<LittleEndian> = serde_json::from_str(&json).unwrap();

    assert_eq!(result, stream);
}

#[cfg(feature = "schemars")]
impl<'a, E: Endianness> schemars::JsonSchema for BitReadStream<'a, E> {
    fn schema_name() -> String {
        "BitReadStream".into()
    }

    fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
        #[derive(schemars::JsonSchema)]
        #[allow(dead_code)]
        struct StreamSchema {
            data: Vec<u8>,
            bit_length: usize,
        }
        StreamSchema::json_schema(gen)
    }
}