Skip to content

Commit

Permalink
cargo formatting + better panic message in testing
Browse files Browse the repository at this point in the history
  • Loading branch information
tibvdm committed May 16, 2024
1 parent a618019 commit bbe0bc7
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 27 deletions.
41 changes: 24 additions & 17 deletions bitarray/src/binary.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! This module provides utilities for reading and writing the bitarray as binary.

use std::io::{BufRead, Read, Result, Write};
use std::io::{
BufRead,
Read,
Result,
Write
};

use crate::BitArray;

Expand Down Expand Up @@ -61,11 +66,12 @@ impl<const B: usize> Binary for BitArray<B> {
self.data.clear();

let mut buffer = vec![0; 8 * 1024];

loop {
let (finished, bytes_read) = fill_buffer(&mut reader, &mut buffer);
for buffer_slice in buffer[..bytes_read].chunks_exact(8) {
self.data.push(u64::from_le_bytes(buffer_slice.try_into().unwrap()));
for buffer_slice in buffer[.. bytes_read].chunks_exact(8) {
self.data
.push(u64::from_le_bytes(buffer_slice.try_into().unwrap()));
}

if finished {
Expand All @@ -86,8 +92,8 @@ impl<const B: usize> Binary for BitArray<B> {
///
/// # Returns
///
/// Returns a tuple `(finished, bytes_read)` where `finished` indicates whether the end of the input is reached,
/// and `bytes_read` is the number of bytes read into the buffer.
/// Returns a tuple `(finished, bytes_read)` where `finished` indicates whether the end of the input
/// is reached, and `bytes_read` is the number of bytes read into the buffer.
fn fill_buffer<T: Read>(input: &mut T, buffer: &mut Vec<u8>) -> (bool, usize) {
// Store the buffer size in advance, because rust will complain
// about the buffer being borrowed mutably while it's borrowed
Expand All @@ -109,7 +115,7 @@ fn fill_buffer<T: Read>(input: &mut T, buffer: &mut Vec<u8>) -> (bool, usize) {
// We've read {bytes_read} bytes
Ok(bytes_read) => {
// Shrink the writable buffer slice
writable_buffer_space = writable_buffer_space[bytes_read..].as_mut();
writable_buffer_space = writable_buffer_space[bytes_read ..].as_mut();
}

Err(err) => {
Expand Down Expand Up @@ -137,7 +143,7 @@ mod tests {
let mut input = input_str.as_bytes();

let mut buffer = vec![0; 800];

loop {
let (finished, bytes_read) = fill_buffer(&mut input, &mut buffer);

Expand All @@ -151,7 +157,7 @@ mod tests {
}

#[test]
#[should_panic]
#[should_panic(expected = "Error while reading input:")]
fn test_fill_buffer_read_error() {
let mut input = ErrorInput;
let mut buffer = vec![0; 800];
Expand All @@ -170,19 +176,20 @@ mod tests {
let mut buffer = Vec::new();
bitarray.write_binary(&mut buffer).unwrap();

assert_eq!(buffer, vec![
0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12,
0xde, 0xbc, 0x0a, 0x89, 0x67, 0x45, 0x23, 0x01,
0x00, 0x00, 0x00, 0x00, 0x56, 0x34, 0x12, 0xf0
]);
assert_eq!(
buffer,
vec![
0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12, 0xde, 0xbc, 0x0a, 0x89, 0x67, 0x45,
0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x56, 0x34, 0x12, 0xf0
]
);
}

#[test]
fn test_read_binary() {
let buffer = vec![
0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12,
0xde, 0xbc, 0x0a, 0x89, 0x67, 0x45, 0x23, 0x01,
0x00, 0x00, 0x00, 0x00, 0x56, 0x34, 0x12, 0xf0
0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12, 0xde, 0xbc, 0x0a, 0x89, 0x67, 0x45,
0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x56, 0x34, 0x12, 0xf0,
];

let mut bitarray = BitArray::<40>::with_capacity(4);
Expand Down
22 changes: 12 additions & 10 deletions bitarray/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct BitArray<const B: usize> {
/// The mask used to extract the relevant bits from each element in the data vector.
mask: u64,
/// The length of the bit array.
len: usize,
len: usize
}

impl<const B: usize> BitArray<B> {
Expand All @@ -29,7 +29,7 @@ impl<const B: usize> BitArray<B> {
Self {
data: vec![0; capacity * B / 64 + 1],
mask: (1 << B) - 1,
len: capacity,
len: capacity
}
}

Expand All @@ -48,18 +48,20 @@ impl<const B: usize> BitArray<B> {

// If the value is contained within a single block
if start_block_offset + B <= 64 {
// Shift the value to the right so that the relevant bits are in the least significant position
// Then mask out the irrelevant bits
// Shift the value to the right so that the relevant bits are in the least significant
// position Then mask out the irrelevant bits
return self.data[start_block] >> (64 - start_block_offset - B) & self.mask;
}

let end_block = (index + 1) * B / 64;
let end_block_offset = (index + 1) * B % 64;

// Extract the relevant bits from the start block and shift them {end_block_offset} bits to the left
// Extract the relevant bits from the start block and shift them {end_block_offset} bits to
// the left
let a = self.data[start_block] << end_block_offset;

// Extract the relevant bits from the end block and shift them to the least significant position
// Extract the relevant bits from the end block and shift them to the least significant
// position
let b = self.data[end_block] >> (64 - end_block_offset);

// Paste the two values together and mask out the irrelevant bits
Expand Down Expand Up @@ -116,15 +118,15 @@ mod tests {
#[test]
fn test_bitarray_with_capacity() {
let bitarray = BitArray::<40>::with_capacity(4);
assert_eq!(bitarray.data, vec![ 0, 0, 0 ]);
assert_eq!(bitarray.data, vec![0, 0, 0]);
assert_eq!(bitarray.mask, 0xff_ffff_ffff);
assert_eq!(bitarray.len, 4);
}

#[test]
fn test_bitarray_get() {
let mut bitarray = BitArray::<40>::with_capacity(4);
bitarray.data = vec![ 0x1cfac47f32c25261, 0x4dc9f34db6ba5108, 0x9144eb9ca32eb4a4 ];
bitarray.data = vec![0x1cfac47f32c25261, 0x4dc9f34db6ba5108, 0x9144eb9ca32eb4a4];

assert_eq!(bitarray.get(0), 0b0001110011111010110001000111111100110010);
assert_eq!(bitarray.get(1), 0b1100001001010010011000010100110111001001);
Expand All @@ -141,12 +143,12 @@ mod tests {
bitarray.set(2, 0b1111001101001101101101101011101001010001);
bitarray.set(3, 0b0000100010010001010001001110101110011100);

assert_eq!(bitarray.data, vec![ 0x1cfac47f32c25261, 0x4dc9f34db6ba5108, 0x9144EB9C00000000 ]);
assert_eq!(bitarray.data, vec![0x1cfac47f32c25261, 0x4dc9f34db6ba5108, 0x9144EB9C00000000]);
}

#[test]
fn test_bitarray_len() {
let bitarray = BitArray::<40>::with_capacity(4);
assert_eq!(bitarray.len(), 4);
}
}
}

0 comments on commit bbe0bc7

Please sign in to comment.