Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve encapsulation of ByteVec API. #24

Merged
merged 1 commit into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion flacenc-bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ fn write_stream<F: Write>(stream: &Stream, file: &mut F) {
let mut bv = flacenc::bitsink::ByteVec::new();
stream.write(&mut bv).expect("Bitstream formatting failed.");
let mut writer = BufWriter::new(file);
writer.write_all(&bv.bytes).expect("");
writer
.write_all(bv.as_byte_slice())
.expect("Failed to write a bitstream to the file.");
}

/// Collect iterator of `Result`s, and returns values or the first error.
Expand Down
39 changes: 26 additions & 13 deletions src/bitsink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ impl<'a, L: BitSink, R: BitSink> BitSink for Tee<'a, L, R> {
}

pub struct ByteVec {
pub bytes: Vec<u8>,
pub bitlength: usize,
bytes: Vec<u8>,
bitlength: usize,
}

impl Default for ByteVec {
Expand All @@ -124,31 +124,36 @@ impl Default for ByteVec {
}

impl ByteVec {
/// Creates new `ByteVec` instance with the default capacity.
pub fn new() -> Self {
Self {
bytes: vec![],
bitlength: 0usize,
}
}

pub fn with_capacity(capacity: usize) -> Self {
/// Creates new `ByteVec` instance with the specified capacity (in bits).
pub fn with_capacity(capacity_in_bits: usize) -> Self {
Self {
bytes: Vec::with_capacity(capacity / 8 + 1),
bytes: Vec::with_capacity(capacity_in_bits / 8 + 1),
bitlength: 0usize,
}
}

/// Clears the vector, removing all values.
pub fn clear(&mut self) {
self.bytes.clear();
self.bitlength = 0;
}

pub fn reserve(&mut self, capacity: usize) {
self.bytes.reserve(capacity / 8 + 1);
/// Reseerves capacity for at least `additional_in_bits` more bits.
pub fn reserve(&mut self, additional_in_bits: usize) {
self.bytes.reserve(additional_in_bits / 8 + 1);
}

/// Returns the remaining number of bits in the last byte in `self.bytes`.
#[inline]
pub fn rem_bits(&self) -> usize {
fn tail_len(&self) -> usize {
let r = self.bitlength % 8;
if r == 0 {
0
Expand All @@ -157,7 +162,9 @@ impl ByteVec {
}
}

pub fn to_debug_bitstring(&self) -> String {
/// Returns bits in a string for tests.
#[cfg(test)]
fn to_debug_bitstring(&self) -> String {
let mut ret = String::new();
for b in &self.bytes {
ret.push_str(&format!("{b:08b}_"));
Expand All @@ -166,12 +173,13 @@ impl ByteVec {
ret
}

/// Appends first `nbits` bits (from MSB) to the `ByteVec`.
#[inline]
fn write_u64_msbs(&mut self, val: u64, nbits: usize) {
fn push_u64_msbs(&mut self, val: u64, nbits: usize) {
let mut val: u64 = val;
let mut nbits = nbits;
let nbitlength = self.bitlength + nbits;
let r = self.rem_bits();
let r = self.tail_len();

if r != 0 {
let b: u8 = ((val >> (64 - r)) & ((1 << r) - 1)) as u8;
Expand All @@ -192,6 +200,10 @@ impl ByteVec {
}
self.bitlength = nbitlength;
}

pub fn as_byte_slice(&self) -> &[u8] {
&self.bytes
}
}

impl BitSink for ByteVec {
Expand All @@ -206,8 +218,9 @@ impl BitSink for ByteVec {
}
}

#[inline]
fn align_to_byte(&mut self) -> usize {
let r = self.rem_bits();
let r = self.tail_len();
self.bitlength += r;
r
}
Expand All @@ -226,15 +239,15 @@ impl BitSink for ByteVec {
return;
}
let initial_shift = 64 - (std::mem::size_of::<T>() * 8);
self.write_u64_msbs(val.into() << initial_shift, nbits);
self.push_u64_msbs(val.into() << initial_shift, nbits);
}

#[inline]
fn write_lsbs<T: Into<u64>>(&mut self, val: T, nbits: usize) {
if nbits == 0 {
return;
}
self.write_u64_msbs(val.into() << (64 - nbits), nbits);
self.push_u64_msbs(val.into() << (64 - nbits), nbits);
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,8 @@ impl BitRepr for Frame {
}
frame_buffer.align_to_byte();

dest.write_bytes_aligned(&frame_buffer.bytes);
dest.write(crc::Crc::<u16>::new(&CRC_16_FLAC).checksum(&frame_buffer.bytes));
dest.write_bytes_aligned(frame_buffer.as_byte_slice());
dest.write(crc::Crc::<u16>::new(&CRC_16_FLAC).checksum(frame_buffer.as_byte_slice()));
Ok(())
})
}
Expand Down Expand Up @@ -641,8 +641,10 @@ impl BitRepr for FrameHeader {
dest.write_lsbs(foot, footsize);
}

dest.write_bytes_aligned(&header_buffer.borrow().bytes);
dest.write(crc::Crc::<u8>::new(&CRC_8_FLAC).checksum(&header_buffer.borrow().bytes));
dest.write_bytes_aligned(header_buffer.borrow().as_byte_slice());
dest.write(
crc::Crc::<u8>::new(&CRC_8_FLAC).checksum(header_buffer.borrow().as_byte_slice()),
);
Ok(())
})
}
Expand Down
9 changes: 2 additions & 7 deletions src/test_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,11 @@ where
let stream = encoder(src.clone());

let mut file = NamedTempFile::new().expect("Failed to create temp file.");
/*
let mut bv: BitVec<u8, Msb0> = BitVec::with_capacity(stream.count_bits());
stream.write(&mut bv).expect("Bitstream formatting failed.");
file.write_all(bv.as_raw_slice())
.expect("File write failed.");
*/

let mut bv: ByteVec = ByteVec::with_capacity(stream.count_bits());
stream.write(&mut bv).expect("Bitstream formatting failed.");
file.write_all(&bv.bytes).expect("File write failed.");
file.write_all(bv.as_byte_slice())
.expect("File write failed.");

let flac_path = file.into_temp_path();

Expand Down
Loading