cauldron 0.0.1

Pure Rust Audio Decoder
Documentation
use std::cmp;
use std::io;
use std::mem;

/// Extends the functionality of `io::Read` with additional methods
pub trait ReadBuffer: io::Read {
    /// Reads as many bytes as `buf` is long.
    ///
    /// This may issue multiple `read` calls internally. An error is returned
    /// if `read` read 0 bytes before the buffer is full.
    fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()>;

    /// Reads `n` bytes and returns them in a vector.
    fn read_bytes(&mut self, n: usize) -> io::Result<Vec<u8>>;

    /// Skip over `n` bytes.
    fn skip_bytes(&mut self, n: usize) -> io::Result<()>;

    /// Reads a single byte and interprets it as an 8-bit signed integer.
    fn read_i8(&mut self) -> io::Result<i8>;

    /// Reads a single byte and interprets it as an 8-bit unsigned integer.
    fn read_u8(&mut self) -> io::Result<u8>;

    /// Reads two bytes and interprets them as a little-endian 16-bit signed integer.
    fn read_le_i16(&mut self) -> io::Result<i16>;

    /// Reads two bytes and interprets them as a little-endian 16-bit unsigned integer.
    fn read_le_u16(&mut self) -> io::Result<u16>;

    /// Reads two bytes and interprets them as a big-endian 16-bit unsigned integer.
    fn read_be_u16(&mut self) -> io::Result<u16>;

    /// Reads three bytes and interprets them as a little-endian 24-bit signed integer.
    ///
    /// The sign bit will be extended into the most significant byte.
    fn read_le_i24(&mut self) -> io::Result<i32>;

    /// Reads three bytes and interprets them as a little-endian 24-bit unsigned integer.
    ///
    /// The most significant byte will be 0.
    fn read_le_u24(&mut self) -> io::Result<u32>;

    /// Reads three bytes and interprets them as a big-endian 24-bit unsigned integer.
    /// 
    /// Most significant byte will be 0.
    fn read_be_u24(&mut self) -> io::Result<u32>;

    /// Reads four bytes and interprets them as a little-endian 32-bit signed integer.
    fn read_le_i32(&mut self) -> io::Result<i32>;

    /// Reads four bytes and interprets them as a little-endian 32-bit unsigned integer.
    fn read_le_u32(&mut self) -> io::Result<u32>;

    /// Reads four bytes and interprets them as a big-endian 32-bit unsigned integer.
    fn read_be_u32(&mut self) -> io::Result<u32>;

    /// Reads four bytes and interprets them as a little-endian 32-bit IEEE float.
    fn read_le_f32(&mut self) -> io::Result<f32>;
}

impl<R> ReadBuffer for R
where
    R: io::Read,
{
    #[inline(always)]
    fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()> {
        let mut n = 0;
        while n < buf.len() {
            let progress = self.read(&mut buf[n..])?;
            if progress > 0 {
                n += progress;
            } else {
                return Err(io::Error::new(
                    io::ErrorKind::Other,
                    "Failed to read enough bytes.",
                ));
            }
        }
        Ok(())
    }

    #[inline(always)]
    fn read_bytes(&mut self, n: usize) -> io::Result<Vec<u8>> {
        // We allocate a runtime fixed size buffer, and we are going to read
        // into it, so zeroing or filling the buffer is a waste. This method
        // is safe, because the contents of the buffer are only exposed when
        // they have been overwritten completely by the read.
        let mut buf = Vec::with_capacity(n);
        unsafe {
            buf.set_len(n);
        }
        self.read_into(&mut buf[..])?;
        Ok(buf)
    }

    #[inline(always)]
    fn skip_bytes(&mut self, n: usize) -> io::Result<()> {
        // Read from the input in chunks of 1024 bytes at a time, and discard
        // the result. 1024 is a tradeoff between doing a lot of calls, and
        // using too much stack space. This method is not in a hot path, so it
        // can afford to do this.
        let mut n_read = 0;
        let mut buf = [0u8; 1024];
        while n_read < n {
            let end = cmp::min(n - n_read, 1024);
            let progress = self.read(&mut buf[0..end])?;
            if progress > 0 {
                n_read += progress;
            } else {
                return Err(io::Error::new(
                    io::ErrorKind::Other,
                    "Failed to read enough bytes.",
                ));
            }
        }
        Ok(())
    }

    #[inline(always)]
    fn read_u8(&mut self) -> io::Result<u8> {
        let mut buf = [0u8; 1];
        self.read_into(&mut buf)?;
        Ok(buf[0])
    }

    #[inline(always)]
    fn read_i8(&mut self) -> io::Result<i8> {
        self.read_u8().map(|x| x as i8)
    }

    #[inline(always)]
    fn read_le_u16(&mut self) -> io::Result<u16> {
        let mut buf = [0u8; 2];
        self.read_into(&mut buf)?;
        Ok((buf[1] as u16) << 8 | (buf[0] as u16))
    }

    #[inline(always)]
    fn read_be_u16(&mut self) -> io::Result<u16> {
        let mut buf = [0u8; 2];
        self.read_into(&mut buf)?;
        Ok((buf[0] as u16) << 8 | (buf[1] as u16))
    }

    #[inline(always)]
    fn read_le_i16(&mut self) -> io::Result<i16> {
        self.read_le_u16().map(|x| x as i16)
    }

    #[inline(always)]
    fn read_le_u24(&mut self) -> io::Result<u32> {
        let mut buf = [0u8; 3];
        self.read_into(&mut buf)?;
        Ok((buf[2] as u32) << 16 | (buf[1] as u32) << 8 | buf[0] as u32)
    }

    #[inline(always)]
    fn read_be_u24(&mut self) -> io::Result<u32> {
        let mut buf = [0u8; 3];
        self.read_into(&mut buf)?;
        Ok((buf[0] as u32) << 16 | (buf[1] as u32) << 8 | buf[2] as u32)
    }

    #[inline(always)]
    fn read_le_i24(&mut self) -> io::Result<i32> {
        self.read_le_u24().map(|x|
            // Test the sign bit, if it is set, extend the sign bit into the
            // most significant byte.
            if x & (1 << 23) == 0 {
                x as i32
            } else {
                (x | 0xff_00_00_00) as i32
            }
        )
    }

    #[inline(always)]
    fn read_le_u32(&mut self) -> io::Result<u32> {
        let mut buf = [0u8; 4];
        self.read_into(&mut buf)?;
        Ok((buf[3] as u32) << 24
            | (buf[2] as u32) << 16
            | (buf[1] as u32) << 8
            | (buf[0] as u32) << 0)
    }

    #[inline(always)]
    fn read_be_u32(&mut self) -> io::Result<u32> {
        let mut buf = [0u8; 4];
        self.read_into(&mut buf)?;
        Ok((buf[0] as u32) << 24
            | (buf[1] as u32) << 16
            | (buf[2] as u32) << 8
            | (buf[3] as u32) << 0)
    }

    #[inline(always)]
    fn read_le_i32(&mut self) -> io::Result<i32> {
        self.read_le_u32().map(|x| x as i32)
    }

    #[inline(always)]
    fn read_le_f32(&mut self) -> io::Result<f32> {
        self.read_le_u32().map(|u| unsafe { mem::transmute(u) })
    }
}