1
0
Fork 0
mirror of https://codeberg.org/icewind/bitbuffer.git synced 2026-06-03 08:34:07 +02:00

fix reserve not setting bit len correctly

This commit is contained in:
Robin Appelman 2021-07-16 21:04:07 +02:00
commit 9587c7b872
3 changed files with 117 additions and 75 deletions

View file

@ -101,6 +101,15 @@ struct ExpandWriteBuffer<'a, E: Endianness> {
bytes: *mut Vec<u8>, bytes: *mut Vec<u8>,
endianness: PhantomData<E>, endianness: PhantomData<E>,
lifetime: PhantomData<&'a u8>, lifetime: PhantomData<&'a u8>,
parent_bit_len: Option<&'a mut usize>,
}
impl<'a, E: Endianness> Drop for ExpandWriteBuffer<'a, E> {
fn drop(&mut self) {
if let Some(parent_bit_len) = self.parent_bit_len.take() {
*parent_bit_len = self.bit_len;
}
}
} }
impl<'a, E: Endianness> ExpandWriteBuffer<'a, E> { impl<'a, E: Endianness> ExpandWriteBuffer<'a, E> {
@ -110,6 +119,7 @@ impl<'a, E: Endianness> ExpandWriteBuffer<'a, E> {
bytes: bytes as *mut _, bytes: bytes as *mut _,
endianness: PhantomData, endianness: PhantomData,
lifetime: PhantomData, lifetime: PhantomData,
parent_bit_len: None,
} }
} }
@ -177,6 +187,7 @@ impl<'a, E: Endianness> ExpandWriteBuffer<'a, E> {
bytes: self.bytes, bytes: self.bytes,
endianness: PhantomData, endianness: PhantomData,
lifetime: PhantomData, lifetime: PhantomData,
parent_bit_len: Some(&mut self.bit_len),
}, },
) )
} }
@ -187,11 +198,13 @@ fn test_push_expand_be() {
use crate::BigEndian; use crate::BigEndian;
let mut buffer = vec![]; let mut buffer = vec![];
let mut write = ExpandWriteBuffer::new(&mut buffer, BigEndian); {
write.push_bits(0b1101, 4); let mut write = ExpandWriteBuffer::new(&mut buffer, BigEndian);
write.push_bits(0b1, 1); write.push_bits(0b1101, 4);
write.push_bits(0b0, 1); write.push_bits(0b1, 1);
write.push_bits(0b101_01010, 8); write.push_bits(0b0, 1);
write.push_bits(0b101_01010, 8);
}
assert_eq!(vec![0b1101_1_0_10, 0b101010_00], buffer) assert_eq!(vec![0b1101_1_0_10, 0b101010_00], buffer)
} }
@ -201,11 +214,13 @@ fn test_push_expand_le() {
use crate::LittleEndian; use crate::LittleEndian;
let mut buffer = vec![]; let mut buffer = vec![];
let mut write = ExpandWriteBuffer::new(&mut buffer, LittleEndian); {
write.push_bits(0b1101, 4); let mut write = ExpandWriteBuffer::new(&mut buffer, LittleEndian);
write.push_bits(0b1, 1); write.push_bits(0b1101, 4);
write.push_bits(0b0, 1); write.push_bits(0b1, 1);
write.push_bits(0b101_01010, 8); write.push_bits(0b0, 1);
write.push_bits(0b101_01010, 8);
}
assert_eq!(vec![0b10_0_1_1101, 0b00101010], buffer) assert_eq!(vec![0b10_0_1_1101, 0b00101010], buffer)
} }
@ -215,14 +230,16 @@ fn test_push_expand_reserve_be() {
use crate::BigEndian; use crate::BigEndian;
let mut buffer = vec![]; let mut buffer = vec![];
let mut write = ExpandWriteBuffer::new(&mut buffer, BigEndian); {
write.push_bits(0b1101, 4); let mut write = ExpandWriteBuffer::new(&mut buffer, BigEndian);
write.push_bits(0b1101, 4);
let (mut reserved, mut rest) = write.reserve(2); let (mut reserved, mut rest) = write.reserve(2);
rest.push_bits(0b101_01010, 8); rest.push_bits(0b101_01010, 8);
reserved.push_bits(0b1, 1); reserved.push_bits(0b1, 1);
reserved.push_bits(0b0, 1); reserved.push_bits(0b0, 1);
}
assert_eq!(vec![0b1101_1_0_10, 0b101010_00], buffer) assert_eq!(vec![0b1101_1_0_10, 0b101010_00], buffer)
} }
@ -232,14 +249,16 @@ fn test_push_expand_reserve_le() {
use crate::LittleEndian; use crate::LittleEndian;
let mut buffer = vec![]; let mut buffer = vec![];
let mut write = ExpandWriteBuffer::new(&mut buffer, LittleEndian); {
write.push_bits(0b1101, 4); let mut write = ExpandWriteBuffer::new(&mut buffer, LittleEndian);
write.push_bits(0b1101, 4);
let (mut reserved, mut rest) = write.reserve(2); let (mut reserved, mut rest) = write.reserve(2);
rest.push_bits(0b101_01010, 8); rest.push_bits(0b101_01010, 8);
reserved.push_bits(0b1, 1); reserved.push_bits(0b1, 1);
reserved.push_bits(0b0, 1); reserved.push_bits(0b0, 1);
}
assert_eq!(vec![0b10_0_1_1101, 0b00101010], buffer) assert_eq!(vec![0b10_0_1_1101, 0b00101010], buffer)
} }
@ -249,21 +268,22 @@ fn test_push_expand_reserve_resize() {
use crate::LittleEndian; use crate::LittleEndian;
let mut buffer = Vec::with_capacity(1); let mut buffer = Vec::with_capacity(1);
{
let mut write = ExpandWriteBuffer::new(&mut buffer, LittleEndian);
write.push_bits(0b1101, 4);
let mut write = ExpandWriteBuffer::new(&mut buffer, LittleEndian); let (mut reserved, mut rest) = write.reserve(2);
write.push_bits(0b1101, 4); rest.push_bits(0b10, 2);
let (mut reserved, mut rest) = write.reserve(2); // trigger a resize/reallocation
rest.push_bits(0b10, 2); for _ in 0..128 {
rest.push_bits(0x55, 8);
}
// trigger a resize/reallocation reserved.push_bits(0b1, 1);
for _ in 0..128 { reserved.push_bits(0b0, 1);
rest.push_bits(0x55, 8);
} }
reserved.push_bits(0b1, 1);
reserved.push_bits(0b0, 1);
assert_eq!([0b10_0_1_1101, 0x55], buffer[0..2]) assert_eq!([0b10_0_1_1101, 0x55], buffer[0..2])
} }

View file

@ -15,18 +15,22 @@ fn roundtrip<
) { ) {
{ {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, LittleEndian); let size = {
stream.write(&val).unwrap(); let mut stream = BitWriteStream::new(&mut data, LittleEndian);
let size = stream.bit_len(); stream.write(&val).unwrap();
stream.bit_len()
};
let mut read = BitReadStream::new(BitReadBuffer::new_owned(data, LittleEndian)); let mut read = BitReadStream::new(BitReadBuffer::new_owned(data, LittleEndian));
assert_eq!(val, read.read().unwrap()); assert_eq!(val, read.read().unwrap());
assert_eq!(size, read.pos()); assert_eq!(size, read.pos());
} }
{ {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, BigEndian); let size = {
stream.write(&val).unwrap(); let mut stream = BitWriteStream::new(&mut data, BigEndian);
let size = stream.bit_len(); stream.write(&val).unwrap();
stream.bit_len()
};
let mut read = BitReadStream::new(BitReadBuffer::new_owned(data, BigEndian)); let mut read = BitReadStream::new(BitReadBuffer::new_owned(data, BigEndian));
assert_eq!(val, read.read().unwrap()); assert_eq!(val, read.read().unwrap());
assert_eq!(size, read.pos()); assert_eq!(size, read.pos());

View file

@ -3,12 +3,14 @@ use bitbuffer::{BigEndian, BitReadBuffer, BitReadStream, BitWriteStream, LittleE
#[test] #[test]
fn test_write_bool_le() { fn test_write_bool_le() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, LittleEndian); {
let mut stream = BitWriteStream::new(&mut data, LittleEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_bool(false).unwrap(); stream.write_bool(false).unwrap();
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian));
@ -24,12 +26,14 @@ fn test_write_bool_le() {
#[test] #[test]
fn test_write_bool_be() { fn test_write_bool_be() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, BigEndian); {
let mut stream = BitWriteStream::new(&mut data, BigEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_bool(false).unwrap(); stream.write_bool(false).unwrap();
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, BigEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, BigEndian));
@ -45,11 +49,13 @@ fn test_write_bool_be() {
#[test] #[test]
fn test_write_bool_number_le() { fn test_write_bool_number_le() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, LittleEndian); {
let mut stream = BitWriteStream::new(&mut data, LittleEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_int(3253u16, 16).unwrap(); stream.write_int(3253u16, 16).unwrap();
stream.write_int(13253u64, 64).unwrap(); stream.write_int(13253u64, 64).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian));
@ -64,11 +70,13 @@ fn test_write_bool_number_le() {
#[test] #[test]
fn test_write_bool_number_be() { fn test_write_bool_number_be() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, BigEndian); {
let mut stream = BitWriteStream::new(&mut data, BigEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_int(3253u16, 16).unwrap(); stream.write_int(3253u16, 16).unwrap();
stream.write_int(13253u64, 64).unwrap(); stream.write_int(13253u64, 64).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, BigEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, BigEndian));
@ -83,10 +91,12 @@ fn test_write_bool_number_be() {
#[test] #[test]
fn test_write_float_le() { fn test_write_float_le() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, LittleEndian); {
let mut stream = BitWriteStream::new(&mut data, LittleEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_float(3253.12f32).unwrap(); stream.write_float(3253.12f32).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian));
@ -100,10 +110,12 @@ fn test_write_float_le() {
#[test] #[test]
fn test_write_float_be() { fn test_write_float_be() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, BigEndian); {
let mut stream = BitWriteStream::new(&mut data, BigEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_float(3253.12f32).unwrap(); stream.write_float(3253.12f32).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, BigEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, BigEndian));
@ -117,11 +129,13 @@ fn test_write_float_be() {
#[test] #[test]
fn test_write_string_le() { fn test_write_string_le() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, LittleEndian); {
let mut stream = BitWriteStream::new(&mut data, LittleEndian);
stream.write_string("null terminated", None).unwrap(); stream.write_string("null terminated", None).unwrap();
stream.write_string("fixed length1", Some(16)).unwrap(); stream.write_string("fixed length1", Some(16)).unwrap();
stream.write_string("fixed length2", Some(16)).unwrap(); stream.write_string("fixed length2", Some(16)).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian));
@ -133,12 +147,14 @@ fn test_write_string_le() {
#[test] #[test]
fn test_write_string_le_unaligned() { fn test_write_string_le_unaligned() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, LittleEndian); {
let mut stream = BitWriteStream::new(&mut data, LittleEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_string("null terminated", None).unwrap(); stream.write_string("null terminated", None).unwrap();
stream.write_string("fixed length1", Some(16)).unwrap(); stream.write_string("fixed length1", Some(16)).unwrap();
stream.write_string("fixed length2", Some(16)).unwrap(); stream.write_string("fixed length2", Some(16)).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian));
@ -154,11 +170,13 @@ fn test_write_string_le_unaligned() {
#[test] #[test]
fn test_write_signed() { fn test_write_signed() {
let mut data = Vec::new(); let mut data = Vec::new();
let mut stream = BitWriteStream::new(&mut data, LittleEndian); {
let mut stream = BitWriteStream::new(&mut data, LittleEndian);
stream.write_bool(true).unwrap(); stream.write_bool(true).unwrap();
stream.write_int(-17i32, 32).unwrap(); stream.write_int(-17i32, 32).unwrap();
stream.write_int(-9i32, 8).unwrap(); stream.write_int(-9i32, 8).unwrap();
}
let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian)); let mut read = BitReadStream::from(BitReadBuffer::new(&data, LittleEndian));