alac 0.4.0

An ALAC decoder in Rust.
Documentation
#[derive(Clone)]
pub struct BitCursor<'a> {
    buf: &'a [u8],
    position: usize,
    bit_position: u8,
}

impl<'a> BitCursor<'a> {
    pub fn new(buf: &'a [u8]) -> BitCursor<'a> {
        BitCursor {
            buf: buf,
            position: 0,
            bit_position: 0,
        }
    }

    #[inline]
    pub fn read_bit(&mut self) -> Result<bool, ()> {
        self.read_u8(1).map(|b| {
            match b {
                0 => false,
                1 => true,
                _ => unreachable!(),
            }
        })
    }

    #[inline]
    pub fn read_u8(&mut self, len: usize) -> Result<u8, ()> {
        assert!(len <= 8);
        try!(self.check_avail(len));

        let ret: u16 = ((self.buf[self.position] as u16) << 8) +
                       *self.buf.get(self.position + 1).unwrap_or(&0) as u16;
        let ret = ret << self.bit_position;
        let ret = ret >> (16 - len);

        self.skip_unckecked(len);

        Ok(ret as u8)
    }

    #[inline]
    pub fn read_u16(&mut self, len: usize) -> Result<u16, ()> {
        assert!(len <= 16);
        try!(self.check_avail(len));

        let ret: u32 = ((self.buf[self.position] as u32) << 16) +
                       ((*self.buf.get(self.position + 1).unwrap_or(&0) as u32) << 8) +
                       *self.buf.get(self.position + 2).unwrap_or(&0) as u32;

        let ret = ret << 8 + self.bit_position;
        let ret = ret >> (32 - len);

        self.skip_unckecked(len);

        Ok(ret as u16)
    }

    #[inline]
    pub fn peek_u32(&mut self, len: usize) -> Result<u32, ()> {
        assert!(len <= 32);
        try!(self.check_avail(len));

        let ret: u64 = ((self.buf[self.position] as u64) << 32) +
                       ((*self.buf.get(self.position + 1).unwrap_or(&0) as u64) << 24) +
                       ((*self.buf.get(self.position + 2).unwrap_or(&0) as u64) << 16) +
                       ((*self.buf.get(self.position + 3).unwrap_or(&0) as u64) << 8) +
                       (*self.buf.get(self.position + 4).unwrap_or(&0) as u64);

        let ret = ret << 24 + self.bit_position;
        let ret = ret >> (64 - len);

        Ok(ret as u32)
    }

    #[inline]
    pub fn read_u32(&mut self, len: usize) -> Result<u32, ()> {
        let ret = try!(self.peek_u32(len));
        self.skip_unckecked(len);
        Ok(ret)
    }


    #[inline]
    fn check_avail(&self, bit_len: usize) -> Result<(), ()> {
        let bit_pos = self.bit_position as usize + bit_len;
        let pos = self.position + bit_pos >> 3;

        if pos < self.buf.len() {
            Ok(())
        } else {
            Err(())
        }
    }

    #[inline]
    pub fn skip(&mut self, bit_len: usize) -> Result<(), ()> {
        try!(self.check_avail(bit_len));
        self.skip_unckecked(bit_len);
        Ok(())
    }

    #[inline]
    fn skip_unckecked(&mut self, bit_len: usize) {
        let bit_pos = self.bit_position as usize + bit_len;

        self.position += bit_pos >> 3;
        self.bit_position = (bit_pos & 7) as u8;
    }

    #[inline]
    pub fn skip_to_byte(&mut self) -> Result<(), ()> {
        let skip = self.bit_position & 7;
        self.skip(skip as usize)
    }
}