add better panic messages on oob index

This commit is contained in:
Vinzenz Schroeter 2024-05-17 23:48:30 +02:00
parent 312fff95b3
commit 6a2ee5fcfa
5 changed files with 35 additions and 7 deletions

View file

@ -1,6 +1,7 @@
/// A vector of bits
#[derive(Clone, PartialEq)]
pub struct BitVec {
size: usize,
data: Vec<u8>,
}
@ -15,6 +16,7 @@ impl BitVec {
pub fn new(size: usize) -> BitVec {
assert_eq!(size % 8, 0);
Self {
size,
data: vec![0; size / 8],
}
}
@ -73,7 +75,7 @@ impl BitVec {
/// Gets the length in bits
pub fn len(&self) -> usize {
self.data.len() * 8
self.size
}
/// returns true if length is 0.
@ -87,9 +89,13 @@ impl BitVec {
}
/// Calculates the byte index and bitmask for a specific bit in the vector
fn get_indexes(&self, index: usize) -> (usize, u8) {
let byte_index = index / 8;
let bit_in_byte_index = 7 - index % 8;
fn get_indexes(&self, bit_index: usize) -> (usize, u8) {
if bit_index >= self.size {
panic!("bit index {bit_index} is outside of range 0..<{}", self.size)
}
let byte_index = bit_index / 8;
let bit_in_byte_index = 7 - bit_index % 8;
let bit_mask: u8 = 1 << bit_in_byte_index;
(byte_index, bit_mask)
}
@ -106,6 +112,7 @@ impl From<&[u8]> for BitVec {
/// Interpret the data as a series of bits and load then into a new `BitVec` instance.
fn from(value: &[u8]) -> Self {
Self {
size: value.len() * 8,
data: Vec::from(value),
}
}

View file

@ -38,11 +38,13 @@ impl ByteGrid {
///
/// returns: current byte value
pub fn get(&self, x: usize, y: usize) -> u8 {
self.check_indexes(x, y);
self.data[x + y * self.width]
}
/// Sets the byte value at the specified position
pub fn set(&mut self, x: usize, y: usize, value: u8) {
self.check_indexes(x, y);
self.data[x + y * self.width] = value;
}
@ -65,6 +67,15 @@ impl ByteGrid {
pub fn height(&self) -> usize {
self.height
}
fn check_indexes(&self, x: usize, y: usize) {
if x >= self.width {
panic!("cannot access byte {x}-{y} because x is outside of bounds 0..{}", self.width)
}
if y >= self.height {
panic!("cannot access byte {x}-{y} because y is outside of bounds 0..{}", self.height)
}
}
}
impl From<ByteGrid> for Vec<u8> {

View file

@ -706,7 +706,7 @@ mod tests {
fn error_reserved_used() {
let Packet(header, payload)
= Command::BitmapLinear(0, BitVec::new(8), CompressionCode::Uncompressed).into();
let Header(command, offset, length, sub, reserved) = header;
let Header(command, offset, length, sub, _reserved) = header;
let p = Packet(Header(command, offset, length, sub, 69), payload);
assert_eq!(
Command::try_from(p),
@ -717,7 +717,7 @@ mod tests {
fn error_invalid_compression() {
let Packet(header, payload)
= Command::BitmapLinear(0, BitVec::new(8), CompressionCode::Uncompressed).into();
let Header(command, offset, length, sub, reserved) = header;
let Header(command, offset, length, _sub, reserved) = header;
let p = Packet(Header(command, offset, length, 42, reserved), payload);
assert_eq!(
Command::try_from(p),

View file

@ -51,7 +51,7 @@ impl Connection {
/// pixels.fill(true);
///
/// // send pixels to display
/// connection.send(servicepoint2::Command::BitmapLinearWin(servicepoint2::Origin::top_left(), pixels, CompressionCode::Lzma).into())
/// connection.send(servicepoint2::Command::BitmapLinearWin(servicepoint2::Origin(0, 0), pixels, CompressionCode::Lzma).into())
/// .expect("send failed");
/// ```
pub fn send(&self, packet: Packet) -> Result<(), std::io::Error> {

View file

@ -60,6 +60,7 @@ impl PixelGrid {
/// Sets the byte value at the specified position
pub fn set(&mut self, x: usize, y: usize, value: bool) -> bool {
self.check_indexes(x, y);
self.bit_vec.set(x + y * self.width, value)
}
@ -88,6 +89,15 @@ impl PixelGrid {
pub fn height(&self) -> usize {
self.height
}
fn check_indexes(&self, x: usize, y: usize) {
if x >= self.width {
panic!("cannot access pixel {x}-{y} because x is outside of bounds 0..{}", self.width)
}
if y >= self.height {
panic!("cannot access pixel {x}-{y} because y is outside of bounds 0..{}", self.height)
}
}
}
impl From<PixelGrid> for Vec<u8> {