use core::mem;
use bitvec::{vec::BitVec, bits::Bits, cursor::Cursor, slice::BitSlice, boxed::BitBox};
use byte_slice_cast::{AsByteSlice, ToByteSlice, FromByteSlice};
use crate::codec::{Encode, Decode, Input, Output, Compact};
impl<C: Cursor, T: Bits + ToByteSlice> Encode for BitSlice<C, T> {
fn encode_to<W: Output>(&self, dest: &mut W) {
let len = self.len();
assert!(len <= u32::max_value() as usize, "Attempted to serialize a collection with too many elements.");
Compact(len as u32).encode_to(dest);
dest.write(self.as_slice().as_byte_slice());
}
}
impl<C: Cursor, T: Bits + ToByteSlice> Encode for BitVec<C, T> {
fn encode_to<W: Output>(&self, dest: &mut W) {
self.as_bitslice().encode_to(dest)
}
}
impl<C: Cursor, T: Bits + FromByteSlice> Decode for BitVec<C, T> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
<Compact<u32>>::decode(input).and_then(move |Compact(bits)| {
let bits = bits as usize;
let mut vec = vec![0; required_bytes::<T>(bits)];
if input.read(&mut vec) != vec.len() {
return None;
}
Some(if vec.is_empty() {
Self::new()
} else {
let mut result = Self::from_slice(T::from_byte_slice(&vec).ok()?);
assert!(bits <= result.len());
unsafe { result.set_len(bits); }
result
})
})
}
}
impl<C: Cursor, T: Bits + ToByteSlice> Encode for BitBox<C, T> {
fn encode_to<W: Output>(&self, dest: &mut W) {
self.as_bitslice().encode_to(dest)
}
}
impl<C: Cursor, T: Bits + FromByteSlice> Decode for BitBox<C, T> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Self::from_bitslice(BitVec::<C, T>::decode(input)?.as_bitslice()))
}
}
fn required_bytes<T>(bits: usize) -> usize {
let element_bits = mem::size_of::<T>() * 8;
(bits + element_bits - 1) / element_bits * mem::size_of::<T>()
}
#[cfg(test)]
mod tests {
use super::*;
use bitvec::{bitvec, cursor::BigEndian};
macro_rules! test_data {
($inner_type: ty) => (
[
BitVec::<BigEndian, $inner_type>::new(),
bitvec![BigEndian, $inner_type; 0],
bitvec![BigEndian, $inner_type; 1],
bitvec![BigEndian, $inner_type; 0, 0],
bitvec![BigEndian, $inner_type; 1, 0],
bitvec![BigEndian, $inner_type; 0, 1],
bitvec![BigEndian, $inner_type; 1, 1],
bitvec![BigEndian, $inner_type; 1, 0, 1],
bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1],
bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0],
bitvec![BigEndian, $inner_type; 1, 1, 0, 1, 0, 1, 1, 0, 1],
bitvec![BigEndian, $inner_type; 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0],
bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0],
bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0],
bitvec![BigEndian, $inner_type; 0; 15],
bitvec![BigEndian, $inner_type; 1; 16],
bitvec![BigEndian, $inner_type; 0; 17],
bitvec![BigEndian, $inner_type; 1; 31],
bitvec![BigEndian, $inner_type; 0; 32],
bitvec![BigEndian, $inner_type; 1; 33],
bitvec![BigEndian, $inner_type; 0; 63],
bitvec![BigEndian, $inner_type; 1; 64],
bitvec![BigEndian, $inner_type; 0; 65],
]
)
}
#[test]
fn required_bytes_test() {
assert_eq!(0, required_bytes::<u8>(0));
assert_eq!(1, required_bytes::<u8>(1));
assert_eq!(1, required_bytes::<u8>(7));
assert_eq!(1, required_bytes::<u8>(8));
assert_eq!(2, required_bytes::<u8>(9));
assert_eq!(0, required_bytes::<u16>(0));
assert_eq!(2, required_bytes::<u16>(1));
assert_eq!(2, required_bytes::<u16>(15));
assert_eq!(2, required_bytes::<u16>(16));
assert_eq!(4, required_bytes::<u16>(17));
assert_eq!(0, required_bytes::<u32>(0));
assert_eq!(4, required_bytes::<u32>(1));
assert_eq!(4, required_bytes::<u32>(31));
assert_eq!(4, required_bytes::<u32>(32));
assert_eq!(8, required_bytes::<u32>(33));
assert_eq!(0, required_bytes::<u64>(0));
assert_eq!(8, required_bytes::<u64>(1));
assert_eq!(8, required_bytes::<u64>(63));
assert_eq!(8, required_bytes::<u64>(64));
assert_eq!(16, required_bytes::<u64>(65));
}
#[test]
fn bitvec_u8() {
for v in &test_data!(u8) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u8>::decode(&mut &encoded[..]).unwrap());
}
}
#[test]
fn bitvec_u16() {
for v in &test_data!(u16) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u16>::decode(&mut &encoded[..]).unwrap());
}
}
#[test]
fn bitvec_u32() {
for v in &test_data!(u32) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u32>::decode(&mut &encoded[..]).unwrap());
}
}
#[test]
fn bitvec_u64() {
for v in &test_data!(u64) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u64>::decode(&mut &encoded[..]).unwrap());
}
}
#[test]
fn bitslice() {
let data: &[u8] = &[0x69];
let slice: &BitSlice = data.into();
let encoded = slice.encode();
let decoded = BitVec::<BigEndian, u8>::decode(&mut &encoded[..]).unwrap();
assert_eq!(slice, decoded.as_bitslice());
}
#[test]
fn bitbox() {
let data: &[u8] = &[5, 10];
let bb: BitBox = data.into();
let encoded = bb.encode();
let decoded = BitBox::<BigEndian, u8>::decode(&mut &encoded[..]).unwrap();
assert_eq!(bb, decoded);
}
}