use bitvec::field::BitField;
use itertools::Itertools;
use super::BuszBitSlice;
pub (crate) fn bitslice_to_bytes(bits: &BuszBitSlice) -> Vec<u8>{
assert_eq!(bits.len() % 8, 0, "cant covnert to bytes if Bitsclie is not a multiple of 8");
let nbytes = bits.len() / 8;
let mut bytes = Vec::with_capacity(nbytes);
for i in 0..nbytes {
let b = &bits[i*8.. (i+1)*8];
let a: u8 = b.load_be(); bytes.push(a);
}
bytes
}
pub (crate) fn bitstream_to_string(buffer: &BuszBitSlice) -> String{
let mut s = String::new();
let x = buffer.iter().map(|x| if *x{"1"} else {"0"});
for bit64 in &x.into_iter().chunks(64){
let concat = bit64.collect::<Vec<_>>().join("");
s.push_str(&concat);
s.push('\n');
}
s
}
pub(crate) fn calc_n_trailing_bits(bits_processed: usize) -> usize {
let padded_size = round_to_multiple(bits_processed, 64);
let zeros_toremoved = padded_size - bits_processed;
zeros_toremoved
}
pub (crate) fn swap_endian(bytes: &[u8], wordsize: usize) -> Vec<u8>{
let mut swapped_endian: Vec<u8> = Vec::with_capacity(bytes.len());
for bytes in bytes.chunks(wordsize){
swapped_endian.extend(bytes.iter().rev());
}
swapped_endian
}
pub (crate) fn swap_endian8_swap_endian4(bytes: &[u8], ) -> Vec<u8>{
let mut swapped_endian: Vec<u8> = Vec::with_capacity(bytes.len());
for bytes in bytes.chunks(8){
swapped_endian.extend(&bytes[4..]);
swapped_endian.extend(&bytes[..4]);
}
swapped_endian
}
pub (crate) fn swap_endian8_swap_endian4_inplace(x: &mut [u8]) {
let n_chunks: usize = (x.len() / 8).try_into().expect("must be multiple of 8 (u64=8 bytes!)");
for i in 0..n_chunks {
let pos = i * 8;
x.swap(pos, pos+4);
x.swap(pos+1, pos+5);
x.swap(pos+2, pos+6);
x.swap(pos+3, pos+7);
}
}
pub (crate) fn round_to_multiple(i: usize, multiple: usize) -> usize {
i.next_multiple_of(multiple) }
pub (crate) fn setbits_u32(x: u8) -> u32 {
u32::MAX >> (32 - x)
}
pub (crate) fn setbits_u64(x: u8) -> u64 {
u64::MAX >> (64 - x)
}
#[cfg(test)]
mod test {
use std::io::Read;
use bitvec::{bits, order::Msb0};
use fastfibonacci::utils::create_bitvector;
use super::*;
use crate::busz::utils::{swap_endian, setbits_u32, setbits_u64};
#[test]
fn test_bitslice_to_bytes() {
let b = create_bitvector(vec![
0,0,0,0, 0, 0, 1, 1,
1,1,1,1, 1, 1, 1, 1,
]);
assert_eq!(
bitslice_to_bytes(&b),
vec![3, 255]
);
assert_eq!(
b.bytes().map(|x| x.unwrap()).collect::<Vec<_>>(),
vec![3, 255]
)
}
#[test]
fn test_swap_inmem() {
let b = bits![u64, Msb0;
0,0,0,0, 0, 0, 0, 1,
0,0,0,0, 0, 0, 1, 1,
0,0,0,0, 0, 1, 1, 1,
0,0,0,0, 1, 1, 1, 1,
0,0,0,1, 1, 1, 1, 1,
0,0,1,1, 1, 1, 1, 1,
0,1,1,1, 1, 1, 1, 1,
1,1,1,1, 1, 1, 1, 1,
];
let before = b.bytes().map(|x| x.unwrap()).collect::<Vec<_>>();
println!("{:?}", before);
let bytes_it = b.bytes().map(|x| x.unwrap());
let mut swapped_endian: Vec<u8> = Vec::new();
for bytes in bytes_it.chunks(8).into_iter(){
let b1: Vec<_> = bytes.collect();
swapped_endian.extend(&b1[4..]);
swapped_endian.extend(&b1[..4]);
}
println!("{:?}", swapped_endian)
}
#[test]
fn endian_swapping() {
let v = vec![0_u8,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
let a = swap_endian(&v, 8);
let b = swap_endian(&a, 4);
let c = swap_endian(&b, 4);
let d = swap_endian(&c, 8);
assert_eq!(v,d);
}
#[test]
fn test_setbits_u32() {
assert_eq!(setbits_u32(3), 7);
assert_eq!(setbits_u32(2), 3);
assert_eq!(setbits_u32(1), 1);
}
#[test]
fn test_setbits_u64() {
assert_eq!(setbits_u64(3), 7);
assert_eq!(setbits_u64(2), 3);
assert_eq!(setbits_u64(1), 1);
}
#[test]
fn test_swap_endian8_swap_endian4() {
let x = &[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24];
let y1 = swap_endian8_swap_endian4(x);
let y2 = swap_endian(
&swap_endian(x, 8),
4
);
assert_eq!(y1, y2);
let y3 = swap_endian(
&swap_endian(x, 4),
8
);
assert_eq!(y1, y3);
let mut a: Vec<u8> = x.to_vec();
swap_endian8_swap_endian4_inplace(&mut a);
assert_eq!(y1, a);
}
}