102 lines
2.0 KiB
Rust
102 lines
2.0 KiB
Rust
#[derive(Debug)]
|
|
pub struct BitWriter {
|
|
data: Vec<u8>,
|
|
bits: u8,
|
|
nextbit: usize,
|
|
}
|
|
impl BitWriter {
|
|
pub fn new() -> Self {
|
|
return BitWriter {
|
|
data: vec![],
|
|
bits: 0,
|
|
nextbit: 7,
|
|
};
|
|
}
|
|
pub fn write(&mut self, bit: bool) {
|
|
if bit {
|
|
self.bits = 1 << self.nextbit | self.bits;
|
|
}
|
|
if self.nextbit == 0 {
|
|
self.data.push(self.bits);
|
|
self.bits = 0;
|
|
self.nextbit = 7;
|
|
} else {
|
|
self.nextbit -= 1;
|
|
}
|
|
}
|
|
pub fn flush(mut self) -> Vec<u8> {
|
|
if self.bits != 0 {
|
|
self.data.push(self.bits);
|
|
}
|
|
return self.data;
|
|
}
|
|
}
|
|
|
|
impl Into<Vec<u8>> for BitWriter {
|
|
fn into(self) -> Vec<u8> {
|
|
self.flush()
|
|
}
|
|
}
|
|
impl IntoIterator for BitWriter {
|
|
type Item = u8;
|
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
self.flush().into_iter()
|
|
}
|
|
}
|
|
|
|
pub trait Poppable {
|
|
fn pop(&mut self) -> Option<u8>;
|
|
}
|
|
impl Poppable for &[u8] {
|
|
fn pop(&mut self) -> Option<u8> {
|
|
if self.len() == 0 {
|
|
return None;
|
|
}
|
|
let out = self[0];
|
|
*self = &self[1..];
|
|
return Some(out);
|
|
}
|
|
}
|
|
|
|
pub struct BitReader<'a> {
|
|
data: &'a [u8],
|
|
// bits: u8,
|
|
nextbit: usize,
|
|
}
|
|
|
|
impl<'a> BitReader<'a> {
|
|
pub fn new(data: &'a [u8]) -> Self {
|
|
BitReader { data, nextbit: 7 }
|
|
}
|
|
}
|
|
|
|
impl<'a> From<&'a [u8]> for BitReader<'a> {
|
|
fn from(value: &'a [u8]) -> Self {
|
|
BitReader::new(value)
|
|
}
|
|
}
|
|
|
|
impl BitReader<'_> {
|
|
pub fn pop(&mut self) -> Option<bool> {
|
|
if self.data.len() == 0 {
|
|
return None;
|
|
}
|
|
let bit = (self.data[0] >> self.nextbit) & 1;
|
|
if self.nextbit == 0 {
|
|
self.data.pop();
|
|
self.nextbit = 8;
|
|
}
|
|
self.nextbit -= 1;
|
|
return Some(bit > 0);
|
|
}
|
|
}
|
|
|
|
impl Iterator for BitReader<'_> {
|
|
type Item = bool;
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
self.pop()
|
|
}
|
|
}
|