#![cfg(feature = "std")]
use crate::{
field::BitField,
order::BitOrder,
slice::BitSlice,
store::BitStore,
vec::BitVec,
};
use core::mem;
use std::io::{
self,
Read,
Write,
};
impl<'a, O, T> Read for &'a BitSlice<O, T>
where
O: BitOrder,
T: BitStore,
BitSlice<O, T>: BitField,
{
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let mut idx = 0;
for (byte, slot) in self.chunks_exact(8).zip(buf.iter_mut()) {
*slot = byte.load();
idx += 1;
}
*self = unsafe { self.get_unchecked(idx * 8 ..) };
Ok(idx)
}
}
impl<'a, O, T> Write for &'a mut BitSlice<O, T>
where
O: BitOrder,
T: BitStore,
BitSlice<O, T::Alias>: BitField,
{
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let mut idx = 0;
for (slot, byte) in self.chunks_exact_mut(8).zip(buf.iter().copied()) {
slot.store(byte);
idx += 1;
}
*self = unsafe { mem::take(self).get_unchecked_mut(idx * 8 ..) };
Ok(idx)
}
#[inline(always)]
#[cfg(not(tarpaulin_include))]
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl<O, T> Write for BitVec<O, T>
where
O: BitOrder,
T: BitStore,
BitSlice<O, T::Alias>: BitField,
{
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let len = self.len();
self.resize(len + buf.len() * 8, false);
unsafe { self.get_unchecked_mut(len ..) }.write(buf)
}
#[inline(always)]
#[cfg(not(tarpaulin_include))]
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::prelude::*;
#[test]
fn read_bits() {
let data = [0x136Cu16, 0x8C63];
let mut bits = &data.view_bits::<Msb0>()[4 ..];
assert_eq!(bits.len(), 28);
let mut transfer = [0u8; 4];
let last_ptr = &mut transfer[3] as *mut _;
let mut transfer_handle = &mut transfer[..];
assert_eq!(io::copy(&mut bits, &mut transfer_handle).unwrap(), 3);
assert_eq!(bits, data.view_bits::<Msb0>()[28 ..]);
assert_eq!(transfer_handle.as_mut_ptr() as *mut _, last_ptr);
if cfg!(target_endian = "little") {
assert_eq!(transfer[.. 3], [0x36, 0x8C, 0xC6][..]);
}
}
#[test]
fn write_bits() {
let mut bv = bitvec![Msb0, usize; 0, 0, 0, 0];
assert_eq!(
3,
io::copy(&mut &[0xC3u8, 0xF0, 0x69][..], &mut bv).unwrap()
);
assert_eq!(bv, bits![
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1,
]);
}
}