From 58dfe753cff488c9be5ec039388878feae3a5a18 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Tue, 1 Jul 2025 12:01:44 +0300 Subject: [PATCH] Implement `ByteVacuumer` --- Cargo.toml | 1 + src/memory/bytevacuumer/Cargo.toml | 19 + src/memory/bytevacuumer/bytevacuumer/mod.rs | 106 +++ src/memory/bytevacuumer/bytevacuumer/tests.rs | 689 ++++++++++++++++++ src/memory/bytevacuumer/mod.rs | 1 + src/memory/endianness/endianness/mod.rs | 2 +- src/memory/endianness/endianness/tests.rs | 2 +- 7 files changed, 818 insertions(+), 2 deletions(-) create mode 100644 src/memory/bytevacuumer/Cargo.toml create mode 100644 src/memory/bytevacuumer/bytevacuumer/mod.rs create mode 100644 src/memory/bytevacuumer/bytevacuumer/tests.rs create mode 100644 src/memory/bytevacuumer/mod.rs diff --git a/Cargo.toml b/Cargo.toml index c126089..83fb334 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "src/memory/bitstreamcache", "src/memory/bitstreamer", "src/memory/variable_length_load", + "src/memory/bytevacuumer", ] [workspace.package] diff --git a/src/memory/bytevacuumer/Cargo.toml b/src/memory/bytevacuumer/Cargo.toml new file mode 100644 index 0000000..f26b5e0 --- /dev/null +++ b/src/memory/bytevacuumer/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "rawspeed-memory-bytevacuumer" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +documentation.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true + +[lints] +workspace = true + +[dependencies] +rawspeed-memory-endianness = { path = "../endianness" } + +[lib] +path = "mod.rs" diff --git a/src/memory/bytevacuumer/bytevacuumer/mod.rs b/src/memory/bytevacuumer/bytevacuumer/mod.rs new file mode 100644 index 0000000..6e81e4f --- /dev/null +++ b/src/memory/bytevacuumer/bytevacuumer/mod.rs @@ -0,0 +1,106 @@ +use rawspeed_memory_endianness::endianness::Endianness; +use rawspeed_memory_endianness::endianness::SwapBytes; +use rawspeed_memory_endianness::endianness::get_host_endianness; + +pub trait ToBits { + type Output; + fn to_bits(self) -> Self::Output; +} + +macro_rules! impl_to_bits { + ($src:ty, $tgt:ty) => { + impl ToBits for $src { + type Output = $tgt; + fn to_bits(self) -> Self::Output { + Self::Output::from_ne_bytes(self.to_ne_bytes()) + } + } + }; +} + +impl_to_bits!(u8, u8); +impl_to_bits!(i8, u8); +impl_to_bits!(u16, u16); +impl_to_bits!(i16, u16); +impl_to_bits!(u32, u32); +impl_to_bits!(i32, u32); +impl_to_bits!(u64, u64); +impl_to_bits!(i64, u64); + +impl_to_bits!(f32, u32); +impl_to_bits!(f64, u64); + +pub trait ToNeBytes { + type Output; + fn to_ne_bytes(self) -> Self::Output; +} + +impl ToNeBytes for u8 { + type Output = [u8; 1]; + + fn to_ne_bytes(self) -> Self::Output { + self.to_ne_bytes() + } +} + +impl ToNeBytes for u16 { + type Output = [u8; 2]; + + fn to_ne_bytes(self) -> Self::Output { + self.to_ne_bytes() + } +} + +impl ToNeBytes for u32 { + type Output = [u8; 4]; + + fn to_ne_bytes(self) -> Self::Output { + self.to_ne_bytes() + } +} + +impl ToNeBytes for u64 { + type Output = [u8; 8]; + + fn to_ne_bytes(self) -> Self::Output { + self.to_ne_bytes() + } +} + +pub struct ByteVacuumer<'a, W> +where + W: std::io::Write, +{ + writer: &'a mut W, + endianness: Endianness, +} + +impl<'a, W> ByteVacuumer<'a, W> +where + W: std::io::Write, +{ + #[allow(dead_code)] + pub const fn new(writer: &'a mut W, endianness: Endianness) -> Self { + Self { writer, endianness } + } + + #[allow(dead_code)] + fn write(&mut self, val: T) -> std::io::Result<()> + where + T: ToBits, + ::Output: SwapBytes + ToNeBytes, + <::Output as ToNeBytes>::Output: + core::ops::Index, + { + let val = val.to_bits(); + let val = + val.get_byte_swapped(get_host_endianness() != self.endianness); + let bytes = val.to_ne_bytes(); + self.writer.write_all(&bytes[..]) + } +} + +#[cfg(test)] +#[allow(clippy::large_stack_frames)] +#[allow(clippy::cast_sign_loss)] +mod tests; diff --git a/src/memory/bytevacuumer/bytevacuumer/tests.rs b/src/memory/bytevacuumer/bytevacuumer/tests.rs new file mode 100644 index 0000000..080122d --- /dev/null +++ b/src/memory/bytevacuumer/bytevacuumer/tests.rs @@ -0,0 +1,689 @@ +use super::*; + +use std::io::Write as _; + +#[test] +fn flush_arr_overflow_test() { + use std::io::Cursor; + let mut buf = [0_u8; 0]; + let mut buf = Cursor::new(buf.as_mut()); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + assert!(vac.write::(0).is_err()); +} + +#[test] +fn u8_enumeration_test() -> std::io::Result<()> { + let inputs: Vec> = + vec![vec![0, u8::MIN, u8::MAX, i8::MIN as u8, i8::MAX as u8]]; + for endianness in [Endianness::Little, Endianness::Big] { + let mut res: Vec> = vec![]; + for input in &inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, endianness); + for val in input { + vac.write::(*val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![0, 0, 255, 128, 127]]; + assert_eq!(res, expected); + } + Ok(()) +} + +#[test] +fn u32_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + u32::from(u8::MIN), + u32::from(u8::MAX), + u32::from(i8::MIN as u8), + u32::from(i8::MAX as u8), + u32::from(u16::MIN), + u32::from(u16::MAX), + u32::from(i16::MIN as u16), + u32::from(i16::MAX as u16), + u32::MIN, + u32::MAX, + i32::MIN as u32, + i32::MAX as u32, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 128, 0, 0, 0, 127, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 128, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 128, 255, 255, 255, 127, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn u16_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + u16::from(u8::MIN), + u16::from(u8::MAX), + u16::from(i8::MIN as u8), + u16::from(i8::MAX as u8), + u16::MIN, + u16::MAX, + i16::MIN as u16, + i16::MAX as u16, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 255, 0, 128, 0, 127, 0, 0, 0, 255, 255, 0, 128, 255, 127, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn u16_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + u16::from(u8::MIN), + u16::from(u8::MAX), + u16::from(i8::MIN as u8), + u16::from(i8::MAX as u8), + u16::MIN, + u16::MAX, + i16::MIN as u16, + i16::MAX as u16, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 255, 0, 128, 0, 127, 0, 0, 255, 255, 128, 0, 127, 255, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn u32_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + u32::from(u8::MIN), + u32::from(u8::MAX), + u32::from(i8::MIN as u8), + u32::from(i8::MAX as u8), + u32::from(u16::MIN), + u32::from(u16::MAX), + u32::from(i16::MIN as u16), + u32::from(i16::MAX as u16), + u32::MIN, + u32::MAX, + i32::MIN as u32, + i32::MAX as u32, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 128, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 255, 255, 0, 0, 128, 0, 0, 0, 127, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 128, 0, 0, 0, 127, 255, 255, 255, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn u64_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + u64::from(u8::MIN), + u64::from(u8::MAX), + u64::from(i8::MIN as u8), + u64::from(i8::MAX as u8), + u64::from(u16::MIN), + u64::from(u16::MAX), + u64::from(i16::MIN as u16), + u64::from(i16::MAX as u16), + u64::from(u32::MIN), + u64::from(u32::MAX), + u64::from(i32::MIN as u32), + u64::from(i32::MAX as u32), + u64::MIN, + u64::MAX, + i64::MIN as u64, + i64::MAX as u64, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 255, + 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 255, 255, 255, 127, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, + 0, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 127, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn u64_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + u64::from(u8::MIN), + u64::from(u8::MAX), + u64::from(i8::MIN as u8), + u64::from(i8::MAX as u8), + u64::from(u16::MIN), + u64::from(u16::MAX), + u64::from(i16::MIN as u16), + u64::from(i16::MAX as u16), + u64::from(u32::MIN), + u64::from(u32::MAX), + u64::from(i32::MIN as u32), + u64::from(i32::MAX as u32), + u64::MIN, + u64::MAX, + i64::MIN as u64, + i64::MAX as u64, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, + 0, 0, 0, 127, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 127, 255, 255, 255, 0, 0, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, + 0, 0, 0, 127, 255, 255, 255, 255, 255, 255, 255, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn i8_enumeration_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![0, i8::MIN, i8::MAX]]; + for endianness in [Endianness::Little, Endianness::Big] { + let mut res: Vec> = vec![]; + for input in &inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, endianness); + for val in input { + vac.write::(*val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![0, 128, 127]]; + assert_eq!(res, expected); + } + Ok(()) +} + +#[test] +fn i16_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + i16::from(u8::MIN), + i16::from(u8::MAX), + i16::from(i8::MIN), + i16::from(i8::MAX), + i16::MIN, + i16::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = + vec![vec![0, 0, 0, 0, 255, 0, 128, 255, 127, 0, 0, 128, 255, 127]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn i16_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + i16::from(u8::MIN), + i16::from(u8::MAX), + i16::from(i8::MIN), + i16::from(i8::MAX), + i16::MIN, + i16::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = + vec![vec![0, 0, 0, 0, 0, 255, 255, 128, 0, 127, 128, 0, 127, 255]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn i32_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + i32::from(u8::MIN), + i32::from(u8::MAX), + i32::from(i8::MIN), + i32::from(i8::MAX), + i32::from(u16::MIN), + i32::from(u16::MAX), + i32::from(i16::MIN), + i32::from(i16::MAX), + i32::MIN, + i32::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 128, 255, 255, 255, 127, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 0, 0, 0, 128, 255, 255, 255, 127, 0, 0, 0, 0, 0, + 128, 255, 255, 255, 127, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn i32_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + i32::from(u8::MIN), + i32::from(u8::MAX), + i32::from(i8::MIN), + i32::from(i8::MAX), + i32::from(u16::MIN), + i32::from(u16::MAX), + i32::from(i16::MIN), + i32::from(i16::MAX), + i32::MIN, + i32::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 128, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 128, 0, 0, 0, 127, 255, 128, 0, + 0, 0, 127, 255, 255, 255, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn i64_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + i64::from(u8::MIN), + i64::from(u8::MAX), + i64::from(i8::MIN), + i64::from(i8::MAX), + i64::from(u16::MIN), + i64::from(u16::MAX), + i64::from(i16::MIN), + i64::from(i16::MAX), + i64::from(u32::MIN), + i64::from(u32::MAX), + i64::from(i32::MIN), + i64::from(i32::MAX), + i64::MIN, + i64::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, + 0, 128, 255, 255, 255, 255, 255, 255, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 128, 255, 255, 255, + 255, 255, 255, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, + 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 255, 255, 255, 255, + 255, 255, 255, 127, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn i64_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0, + i64::from(u8::MIN), + i64::from(u8::MAX), + i64::from(i8::MIN), + i64::from(i8::MAX), + i64::from(u16::MIN), + i64::from(u16::MAX), + i64::from(i16::MIN), + i64::from(i16::MAX), + i64::from(u32::MIN), + i64::from(u32::MAX), + i64::from(i32::MIN), + i64::from(i32::MAX), + i64::MIN, + i64::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 128, 0, 0, 0, 0, 0, 0, 0, 127, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, 0, + 0, 0, 127, 255, 255, 255, 128, 0, 0, 0, 0, 0, 0, 0, 127, 255, 255, 255, + 255, 255, 255, 255, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn f32_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0.0, + f32::from(u8::MIN), + f32::from(u8::MAX), + f32::from(i8::MIN), + f32::from(i8::MAX), + f32::from(u16::MIN), + f32::from(u16::MAX), + f32::from(i16::MIN), + f32::from(i16::MAX), + f32::MIN, + f32::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 67, 0, 0, 0, 195, 0, 0, 254, 66, 0, + 0, 0, 0, 0, 255, 127, 71, 0, 0, 0, 199, 0, 254, 255, 70, 255, 255, 127, + 255, 255, 255, 127, 127, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn f32_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0.0, + f32::from(u8::MIN), + f32::from(u8::MAX), + f32::from(i8::MIN), + f32::from(i8::MAX), + f32::from(u16::MIN), + f32::from(u16::MAX), + f32::from(i16::MIN), + f32::from(i16::MAX), + f32::MIN, + f32::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 67, 127, 0, 0, 195, 0, 0, 0, 66, 254, 0, 0, 0, + 0, 0, 0, 71, 127, 255, 0, 199, 0, 0, 0, 70, 255, 254, 0, 255, 127, 255, + 255, 127, 127, 255, 255, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn f64_enumeration_le_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0.0, + f64::from(u8::MIN), + f64::from(u8::MAX), + f64::from(i8::MIN), + f64::from(i8::MAX), + f64::from(u16::MIN), + f64::from(u16::MAX), + f64::from(i16::MIN), + f64::from(i16::MAX), + f64::from(u32::MIN), + f64::from(u32::MAX), + f64::from(i32::MIN), + f64::from(i32::MAX), + f64::MIN, + f64::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, + 111, 64, 0, 0, 0, 0, 0, 0, 96, 192, 0, 0, 0, 0, 0, 192, 95, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 255, 239, 64, 0, 0, 0, 0, 0, 0, 224, + 192, 0, 0, 0, 0, 192, 255, 223, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, + 255, 255, 255, 239, 65, 0, 0, 0, 0, 0, 0, 224, 193, 0, 0, 192, 255, + 255, 255, 223, 65, 255, 255, 255, 255, 255, 255, 239, 255, 255, 255, + 255, 255, 255, 255, 239, 127, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn f64_enumeration_be_test() -> std::io::Result<()> { + let inputs: Vec> = vec![vec![ + 0.0, + f64::from(u8::MIN), + f64::from(u8::MAX), + f64::from(i8::MIN), + f64::from(i8::MAX), + f64::from(u16::MIN), + f64::from(u16::MAX), + f64::from(i16::MIN), + f64::from(i16::MAX), + f64::from(u32::MIN), + f64::from(u32::MAX), + f64::from(i32::MIN), + f64::from(i32::MAX), + f64::MIN, + f64::MAX, + ]]; + let mut res: Vec> = vec![]; + for input in inputs { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + for val in input { + vac.write::(val)?; + } + buf.flush()?; + res.push(buf.get_ref().clone()); + } + let expected: Vec> = vec![vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 111, 224, 0, 0, 0, + 0, 0, 192, 96, 0, 0, 0, 0, 0, 0, 64, 95, 192, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 239, 255, 224, 0, 0, 0, 0, 192, 224, 0, 0, 0, 0, 0, + 0, 64, 223, 255, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 239, 255, + 255, 255, 224, 0, 0, 193, 224, 0, 0, 0, 0, 0, 0, 65, 223, 255, 255, + 255, 192, 0, 0, 255, 239, 255, 255, 255, 255, 255, 255, 127, 239, 255, + 255, 255, 255, 255, 255, + ]]; + assert_eq!(res, expected); + Ok(()) +} + +#[test] +fn everything_le_test() -> std::io::Result<()> { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Little); + vac.write::(42_u8)?; + vac.write::(42_u16)?; + vac.write::(42_u32)?; + vac.write::(42_u64)?; + vac.write::(42.0)?; + vac.write::(42.0)?; + buf.flush()?; + let expected: Vec = vec![ + 42, 42, 0, 42, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 66, 0, 0, 0, + 0, 0, 0, 69, 64, + ]; + assert_eq!(*buf.get_ref(), expected); + Ok(()) +} + +#[test] +fn everything_be_test() -> std::io::Result<()> { + use std::io::Cursor; + let mut buf = Cursor::new(vec![]); + let mut vac = ByteVacuumer::new(&mut buf, Endianness::Big); + vac.write::(42_u8)?; + vac.write::(42_u16)?; + vac.write::(42_u32)?; + vac.write::(42_u64)?; + vac.write::(42.0)?; + vac.write::(42.0)?; + buf.flush()?; + let expected: Vec = vec![ + 42, 0, 42, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 42, 66, 40, 0, 0, 64, 69, + 0, 0, 0, 0, 0, 0, + ]; + assert_eq!(*buf.get_ref(), expected); + Ok(()) +} diff --git a/src/memory/bytevacuumer/mod.rs b/src/memory/bytevacuumer/mod.rs new file mode 100644 index 0000000..6c6d725 --- /dev/null +++ b/src/memory/bytevacuumer/mod.rs @@ -0,0 +1 @@ +mod bytevacuumer; diff --git a/src/memory/endianness/endianness/mod.rs b/src/memory/endianness/endianness/mod.rs index 2b88d86..2620ad6 100644 --- a/src/memory/endianness/endianness/mod.rs +++ b/src/memory/endianness/endianness/mod.rs @@ -49,7 +49,7 @@ macro_rules! impl_swap_bytes { }; } -impl_swap_bytes!(u16 u32 u64); +impl_swap_bytes!(u8 u16 u32 u64); #[cfg(test)] #[allow(clippy::large_stack_frames)] diff --git a/src/memory/endianness/endianness/tests.rs b/src/memory/endianness/endianness/tests.rs index 9c26bf5..2d48954 100644 --- a/src/memory/endianness/endianness/tests.rs +++ b/src/memory/endianness/endianness/tests.rs @@ -53,7 +53,7 @@ fn swap_bytes_test() { }; } - test!(u16 u32 u64); + test!(u8 u16 u32 u64); } #[test]