mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-04 00:54:07 +02:00
move bounds check to higher functions
This commit is contained in:
parent
bd012039d0
commit
589928921e
1 changed files with 53 additions and 24 deletions
|
|
@ -7,10 +7,10 @@ use std::ops::BitOrAssign;
|
||||||
|
|
||||||
use num_traits::{Float, PrimInt};
|
use num_traits::{Float, PrimInt};
|
||||||
|
|
||||||
|
use crate::{ReadError, Result};
|
||||||
use crate::endianness::Endianness;
|
use crate::endianness::Endianness;
|
||||||
use crate::is_signed::IsSigned;
|
use crate::is_signed::IsSigned;
|
||||||
use crate::unchecked_primitive::{UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
use crate::unchecked_primitive::{UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||||
use crate::{ReadError, Result};
|
|
||||||
|
|
||||||
const USIZE_SIZE: usize = size_of::<usize>();
|
const USIZE_SIZE: usize = size_of::<usize>();
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ const USIZE_SIZE: usize = size_of::<usize>();
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct BitBuffer<E>
|
pub struct BitBuffer<E>
|
||||||
where
|
where
|
||||||
E: Endianness,
|
E: Endianness,
|
||||||
{
|
{
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
|
|
@ -44,7 +44,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> BitBuffer<E>
|
impl<E> BitBuffer<E>
|
||||||
where
|
where
|
||||||
E: Endianness,
|
E: Endianness,
|
||||||
{
|
{
|
||||||
/// Create a new BitBuffer from a byte vector
|
/// Create a new BitBuffer from a byte vector
|
||||||
|
|
@ -72,7 +72,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> BitBuffer<E>
|
impl<E> BitBuffer<E>
|
||||||
where
|
where
|
||||||
E: Endianness,
|
E: Endianness,
|
||||||
{
|
{
|
||||||
/// The available number of bits in the buffer
|
/// The available number of bits in the buffer
|
||||||
|
|
@ -86,19 +86,6 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_usize(&self, position: usize, count: usize) -> Result<usize> {
|
fn read_usize(&self, position: usize, count: usize) -> Result<usize> {
|
||||||
if position + count > self.bit_len {
|
|
||||||
if position > self.bit_len {
|
|
||||||
return Err(ReadError::IndexOutOfBounds {
|
|
||||||
pos: position,
|
|
||||||
size: self.bit_len,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return Err(ReadError::NotEnoughData {
|
|
||||||
requested: count,
|
|
||||||
bits_left: self.bit_len - position,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let byte_index = min(position / 8, self.byte_len - USIZE_SIZE);
|
let byte_index = min(position / 8, self.byte_len - USIZE_SIZE);
|
||||||
let bit_offset = position - byte_index * 8;
|
let bit_offset = position - byte_index * 8;
|
||||||
let raw_container: &usize = unsafe {
|
let raw_container: &usize = unsafe {
|
||||||
|
|
@ -206,6 +193,20 @@ where
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if position + count > self.bit_len {
|
||||||
|
if position > self.bit_len {
|
||||||
|
return Err(ReadError::IndexOutOfBounds {
|
||||||
|
pos: position,
|
||||||
|
size: self.bit_len,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Err(ReadError::NotEnoughData {
|
||||||
|
requested: count,
|
||||||
|
bits_left: self.bit_len - position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let bit_offset = position & 7;
|
let bit_offset = position & 7;
|
||||||
if size_of::<usize>() > size_of::<T>() || count + bit_offset < usize_bit_size {
|
if size_of::<usize>() > size_of::<T>() || count + bit_offset < usize_bit_size {
|
||||||
let raw = self.read_usize(position, count)?;
|
let raw = self.read_usize(position, count)?;
|
||||||
|
|
@ -280,6 +281,20 @@ where
|
||||||
///
|
///
|
||||||
/// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
|
/// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
|
||||||
pub fn read_bytes(&self, position: usize, byte_count: usize) -> Result<Vec<u8>> {
|
pub fn read_bytes(&self, position: usize, byte_count: usize) -> Result<Vec<u8>> {
|
||||||
|
if position + byte_count * 8 > self.bit_len {
|
||||||
|
if position > self.bit_len {
|
||||||
|
return Err(ReadError::IndexOutOfBounds {
|
||||||
|
pos: position,
|
||||||
|
size: self.bit_len,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Err(ReadError::NotEnoughData {
|
||||||
|
requested: byte_count * 8,
|
||||||
|
bits_left: self.bit_len - position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut data = Vec::with_capacity(byte_count);
|
let mut data = Vec::with_capacity(byte_count);
|
||||||
let mut byte_left = byte_count;
|
let mut byte_left = byte_count;
|
||||||
let max_read = size_of::<usize>() - 1;
|
let max_read = size_of::<usize>() - 1;
|
||||||
|
|
@ -403,6 +418,20 @@ where
|
||||||
where
|
where
|
||||||
T: Float + UncheckedPrimitiveFloat,
|
T: Float + UncheckedPrimitiveFloat,
|
||||||
{
|
{
|
||||||
|
if position + size_of::<T>() * 8 > self.bit_len {
|
||||||
|
if position > self.bit_len {
|
||||||
|
return Err(ReadError::IndexOutOfBounds {
|
||||||
|
pos: position,
|
||||||
|
size: self.bit_len,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Err(ReadError::NotEnoughData {
|
||||||
|
requested: size_of::<T>() * 8,
|
||||||
|
bits_left: self.bit_len - position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if size_of::<T>() == 4 {
|
if size_of::<T>() == 4 {
|
||||||
let int = if size_of::<T>() < USIZE_SIZE {
|
let int = if size_of::<T>() < USIZE_SIZE {
|
||||||
self.read_usize(position, 32)? as u32
|
self.read_usize(position, 32)? as u32
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue