mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-04 00:54:07 +02:00
more efficient way of getting a usize from byte slice
This commit is contained in:
parent
5a188cb2c5
commit
1db817c70c
1 changed files with 21 additions and 21 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
|
use crate::{ReadError, Result};
|
||||||
use crate::endianness::Endianness;
|
use crate::endianness::Endianness;
|
||||||
use crate::is_signed::IsSigned;
|
use crate::is_signed::IsSigned;
|
||||||
use crate::{ReadError, Result};
|
|
||||||
use num_traits::{Float, PrimInt};
|
use num_traits::{Float, PrimInt};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
@ -63,9 +63,9 @@ impl IsPadded for Padded {
|
||||||
/// let buffer = BitBuffer::from_padded_slice(bytes, 8, LittleEndian);
|
/// let buffer = BitBuffer::from_padded_slice(bytes, 8, LittleEndian);
|
||||||
/// ```
|
/// ```
|
||||||
pub struct BitBuffer<'a, E, S>
|
pub struct BitBuffer<'a, E, S>
|
||||||
where
|
where
|
||||||
E: Endianness,
|
E: Endianness,
|
||||||
S: IsPadded,
|
S: IsPadded,
|
||||||
{
|
{
|
||||||
bytes: &'a [u8],
|
bytes: &'a [u8],
|
||||||
bit_len: usize,
|
bit_len: usize,
|
||||||
|
|
@ -75,8 +75,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> BitBuffer<'a, E, NonPadded>
|
impl<'a, E> BitBuffer<'a, E, NonPadded>
|
||||||
where
|
where
|
||||||
E: Endianness,
|
E: Endianness,
|
||||||
{
|
{
|
||||||
/// Create a new BitBuffer from a byte slice
|
/// Create a new BitBuffer from a byte slice
|
||||||
///
|
///
|
||||||
|
|
@ -104,8 +104,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> BitBuffer<'a, E, Padded>
|
impl<'a, E> BitBuffer<'a, E, Padded>
|
||||||
where
|
where
|
||||||
E: Endianness,
|
E: Endianness,
|
||||||
{
|
{
|
||||||
/// Create a new BitBuffer from a byte slice with included padding
|
/// Create a new BitBuffer from a byte slice with included padding
|
||||||
///
|
///
|
||||||
|
|
@ -146,9 +146,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E, S> BitBuffer<'a, E, S>
|
impl<'a, E, S> BitBuffer<'a, E, S>
|
||||||
where
|
where
|
||||||
E: Endianness,
|
E: Endianness,
|
||||||
S: IsPadded,
|
S: IsPadded,
|
||||||
{
|
{
|
||||||
/// The available number of bits in the buffer
|
/// The available number of bits in the buffer
|
||||||
pub fn bit_len(&self) -> usize {
|
pub fn bit_len(&self) -> usize {
|
||||||
|
|
@ -160,7 +160,6 @@ where
|
||||||
self.byte_len
|
self.byte_len
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
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 + count > self.bit_len {
|
||||||
return Err(ReadError::NotEnoughData {
|
return Err(ReadError::NotEnoughData {
|
||||||
|
|
@ -173,14 +172,15 @@ where
|
||||||
} else {
|
} else {
|
||||||
min(position / 8, self.byte_len - USIZE_SIZE)
|
min(position / 8, self.byte_len - USIZE_SIZE)
|
||||||
};
|
};
|
||||||
//let byte_index = position / 8;
|
|
||||||
let bit_offset = position - byte_index * 8;
|
let bit_offset = position - byte_index * 8;
|
||||||
let slice = &self.bytes[byte_index..byte_index + USIZE_SIZE];
|
let raw_container: &usize = unsafe {
|
||||||
let bytes: [u8; USIZE_SIZE] = unsafe { *(slice.as_ptr() as *const [u8; USIZE_SIZE]) };
|
// this is only safe for us because we're sure that there is enough data in the slice
|
||||||
|
std::mem::transmute(self.bytes.as_ptr().offset(byte_index as isize))
|
||||||
|
};
|
||||||
let container = if E::is_le() {
|
let container = if E::is_le() {
|
||||||
usize::from_le_bytes(bytes)
|
usize::from_le(*raw_container)
|
||||||
} else {
|
} else {
|
||||||
usize::from_be_bytes(bytes)
|
usize::from_be(*raw_container)
|
||||||
};
|
};
|
||||||
let shifted = if E::is_le() {
|
let shifted = if E::is_le() {
|
||||||
container >> bit_offset
|
container >> bit_offset
|
||||||
|
|
@ -247,8 +247,8 @@ where
|
||||||
/// assert_eq!(result, 0b100_0110_10);
|
/// assert_eq!(result, 0b100_0110_10);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn read<T>(&self, position: usize, count: usize) -> Result<T>
|
pub fn read<T>(&self, position: usize, count: usize) -> Result<T>
|
||||||
where
|
where
|
||||||
T: PrimInt + BitOrAssign + IsSigned,
|
T: PrimInt + BitOrAssign + IsSigned,
|
||||||
{
|
{
|
||||||
let value = {
|
let value = {
|
||||||
let type_bit_size = size_of::<T>() * 8;
|
let type_bit_size = size_of::<T>() * 8;
|
||||||
|
|
@ -361,8 +361,8 @@ where
|
||||||
/// let result = buffer.read_float::<f32>(10).unwrap();
|
/// let result = buffer.read_float::<f32>(10).unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn read_float<T>(&self, position: usize) -> Result<T>
|
pub fn read_float<T>(&self, position: usize) -> Result<T>
|
||||||
where
|
where
|
||||||
T: Float,
|
T: Float,
|
||||||
{
|
{
|
||||||
if size_of::<T>() == 4 {
|
if size_of::<T>() == 4 {
|
||||||
let int = self.read::<u32>(position, 32)?;
|
let int = self.read::<u32>(position, 32)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue