pub struct BinaryWriter {
data: Vec<bool>,
}
impl BinaryWriter {
pub fn new(cap: usize) -> Self {
BinaryWriter {
data: Vec::with_capacity(cap),
}
}
pub fn writer_bool(&mut self, val: bool) {
self.data.push(val);
}
pub fn writer_u8(&mut self, val: u8) {
for i in (0..8).rev() {
let t = 1 << i;
self.data.push(t & val == t);
}
}
pub fn write_u32(&mut self, val: u32) {
let bit = 32;
for i in (0..bit).rev() {
let t = 1 << i;
self.data.push(t & val == t);
}
}
pub fn write(&mut self,bit:usize, val: usize) {
let i = self.data.len();
for i in (0..bit).rev() {
let t = 1 << i;
self.data.push(t & val == t);
}
debug_assert_ne!(self.data.len() , i);
}
pub fn write_u64(&mut self, val: u64) {
for i in (0..64).rev() {
let t = 1 << i;
self.data.push(t & val == t);
}
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn need_flush(&self) -> bool {
self.data.len() > 8 * 4
}
pub fn flush(&mut self) -> Vec<u8> {
let mut iter = self.data.chunks_exact(8);
let mut ans = Vec::with_capacity(iter.len());
for it in iter.by_ref() {
let item = it
.iter()
.map(|&e| if e { 1 } else { 0 })
.reduce(|acc, e| (acc << 1) + e)
.unwrap() as u8;
ans.push(item);
}
let mut data = Vec::with_capacity(iter.remainder().len());
for &it in iter.remainder() {
data.push(it);
}
self.data = data;
ans
}
pub fn close(mut self) -> Vec<u8> {
let mut ans = self.flush();
if !self.is_empty() {
let s = 8 - self.len();
let mut a = self
.data
.into_iter()
.map(|f| if f { 1 } else { 0 })
.reduce(|acc, e| (acc << 1) + e)
.unwrap() as u8;
a <<= s;
ans.push(a);
}
ans
}
}
#[cfg(test)]
mod test {
use super::BinaryWriter;
#[test]
fn test() {
let mut writer = BinaryWriter::new(120);
writer.writer_bool(true);
assert_eq!(writer.data.len(), 1);
assert_eq!(writer.data, vec![true]);
writer.writer_bool(false);
assert_eq!(writer.data, vec![true, false]);
writer.writer_u8((1 << 2) + (1 << 7));
assert_eq!(writer.len(), 2 + 8);
assert_eq!(
writer.data,
vec![true, false, true, false, false, false, false, true, false, false]
);
writer.write_u64(1 << 2);
assert_eq!(writer.len(), 2 + 8 + 64);
assert!(!writer.data[2 + 8]);
assert!(writer.data[2 + 8 + 64 - 3]);
assert!(writer.need_flush());
println!("{:?}", writer.flush());
assert!(!writer.need_flush());
writer.writer_bool(true);
assert_eq!(writer.close(), vec![1 << (8 - 3)]);
}
}