use crate::BitIter;
#[derive(Debug, Eq, PartialEq)]
pub(super) struct Frame {
cursor: usize,
start: usize,
len: usize,
}
impl Frame {
pub(super) fn new(start: usize, len: usize) -> Self {
Frame {
cursor: start,
start,
len,
}
}
pub(super) fn start(&self) -> usize {
self.start
}
pub(super) fn bit_width(&self) -> usize {
self.len
}
pub(super) fn shallow_copy(&self) -> Self {
Self {
cursor: self.cursor,
start: self.start,
len: self.len,
}
}
pub(super) fn reset_cursor(&mut self) {
self.cursor = self.start;
}
pub(super) fn peek_bit(&self, data: &[u8]) -> bool {
let (byte_index, bit_index) = get_indices(self.cursor);
data[byte_index] & (1 << (7 - bit_index)) != 0
}
pub(super) fn read_bit(&mut self, data: &[u8]) -> bool {
let (byte_index, bit_index) = get_indices(self.cursor);
let bit = data[byte_index] & (1 << (7 - bit_index)) != 0;
self.cursor += 1;
bit
}
pub(super) fn write_bit(&mut self, bit: bool, data: &mut [u8]) {
let (byte_index, bit_index) = get_indices(self.cursor);
let write_mask = 1 << (7 - bit_index);
if bit {
data[byte_index] |= write_mask;
} else {
data[byte_index] &= !write_mask;
}
self.cursor += 1;
}
pub(super) fn write_u8(&mut self, value: u8, data: &mut [u8]) {
for idx in 0..8 {
self.write_bit(value & (1 << (7 - idx)) != 0, data);
}
}
pub(super) fn move_cursor_forward(&mut self, len: usize) {
self.cursor += len;
}
pub(super) fn move_cursor_backward(&mut self, len: usize) {
self.cursor -= len;
}
pub(super) fn copy_from(&mut self, other: &Self, len: usize, data: &mut [u8]) {
for i in 0..len {
let (other_byte_index, other_bit_index) = get_indices(other.cursor + i);
let bit = data[other_byte_index] & (1 << (7 - other_bit_index)) != 0;
self.write_bit(bit, data);
}
}
pub(super) fn as_bit_iter<'a>(
&self,
data: &'a [u8],
) -> BitIter<core::iter::Copied<core::slice::Iter<'a, u8>>> {
BitIter::byte_slice_window(data, self.start, self.start + self.len)
}
}
fn get_indices(cursor: usize) -> (usize, usize) {
let byte_index = cursor / 8;
let bit_index = cursor % 8;
(byte_index, bit_index)
}