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
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
#![cfg(feature = "std")]
#![doc = include_str!("../../doc/field/io.md")]

use core::mem;
use std::io::{
	self,
	Read,
	Write,
};

use super::BitField;
use crate::{
	mem::bits_of,
	order::BitOrder,
	slice::BitSlice,
	store::BitStore,
	vec::BitVec,
};

#[doc = include_str!("../../doc/field/io/Read_BitSlice.md")]
impl<T, O> Read for &BitSlice<T, O>
where
	T: BitStore,
	O: BitOrder,
	BitSlice<T, O>: BitField,
{
	fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
		let mut count = 0;
		self.chunks_exact(bits_of::<u8>())
			.zip(buf.iter_mut())
			.for_each(|(byte, slot)| {
				*slot = byte.load_be();
				count += 1;
			});
		*self = unsafe { self.get_unchecked(count * bits_of::<u8>() ..) };
		Ok(count)
	}
}

#[doc = include_str!("../../doc/field/io/Write_BitSlice.md")]
impl<T, O> Write for &mut BitSlice<T, O>
where
	T: BitStore,
	O: BitOrder,
	BitSlice<T, O>: BitField,
{
	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
		let mut count = 0;
		unsafe { self.chunks_exact_mut(bits_of::<u8>()).remove_alias() }
			.zip(buf.iter().copied())
			.for_each(|(slot, byte)| {
				slot.store_be(byte);
				count += 1;
			});
		*self = unsafe {
			mem::take(self).get_unchecked_mut(count * bits_of::<u8>() ..)
		};
		Ok(count)
	}

	#[cfg(not(tarpaulin_include))]
	fn flush(&mut self) -> io::Result<()> {
		Ok(())
	}
}

#[doc = include_str!("../../doc/field/io/Read_BitVec.md")]
impl<T, O> Read for BitVec<T, O>
where
	T: BitStore,
	O: BitOrder,
	BitSlice<T, O>: BitField,
{
	fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
		let bytes_read = self.as_bitslice().read(buf)?;
		let bits = bytes_read * bits_of::<u8>();
		self.shift_left(bits);
		self.truncate(self.len() - bits);
		Ok(bytes_read)
	}
}

#[doc = include_str!("../../doc/field/io/Write_BitVec.md")]
impl<T, O> Write for BitVec<T, O>
where
	O: BitOrder,
	T: BitStore,
	BitSlice<T, O>: BitField,
{
	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
		let len = self.len();
		self.resize(len + buf.len() * bits_of::<u8>(), false);
		unsafe { self.get_unchecked_mut(len ..) }.write(buf)
	}

	#[cfg(not(tarpaulin_include))]
	fn flush(&mut self) -> io::Result<()> {
		Ok(())
	}
}