1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#[macro_use] extern crate failure_derive;

use async_std::io::{BufReader, Read};
use async_std::prelude::*;

use bitqueue::BitQueue;
use byte_reader::ReadFromBigEndian;
use error::Result;

/// BitReader reads data from a byte slice at the granularity of a single bit.
pub struct BitReader<R : Read + std::marker::Unpin + std::marker::Send> {
    reader : BufReader<R>,
    buffer : BitQueue
}

mod bitqueue;
mod truncate;
mod byte_reader;

pub mod error;

impl<R : Read + std::marker::Unpin + std::marker::Send> BitReader<R>
{
    pub fn new(reader : R) -> BitReader<R>
    {
        BitReader
        {
            reader : BufReader::new(reader),
            buffer : BitQueue::new()
        }
    }

    pub fn is_aligned(&self) -> bool { self.buffer.is_empty() }

    pub async fn read_u8_slice_aligned(&mut self, count : usize) -> Result<Vec<u8>>
    {
        let mut result : Vec<u8> = Vec::with_capacity(count);
        self.reader.read_exact(result.as_mut_slice()).await?;

        Ok(result)
    }

    //should be aligned before this is called
    //Reads a T from the Bitreader and increments position accordingly
    pub async fn read_aligned_be<T>(&mut self) -> Result<T>
    where T : Sized + ReadFromBigEndian + std::marker::Unpin + std::marker::Send
    {
        //check if its aligned to the byte mark
        assert!(self.buffer.is_empty());
        Ok(<T>::read_be(&mut self.reader).await?)
    }

    pub async fn read_bits<T>(&mut self, count: usize) -> Result<T> 
    where T : Sized + std::fmt::Binary +
              std::ops::Shl<usize, Output=T> + 
              std::ops::Shr<usize, Output=T> + ,
          u128: truncate::TruncateTo<T>
    {
        if self.buffer.len() < count
        {

            let mut buf : [u8; 1] = [0;1];

            self.reader.read_exact(&mut buf).await?;
            println!("Result : {:#?}", buf.len());

            let new_bytes : u8 = u8::from_ne_bytes(buf);

            //we need to refil the buffer
            self.buffer.push(new_bytes);
        }

        Ok(self.buffer.pop::<T>(count))
    }
}