From 60232b958ff770357b3cbeaee911d5bc1f231acb Mon Sep 17 00:00:00 2001 From: Trevor Merritt Date: Mon, 2 Jun 2025 09:12:16 -0400 Subject: [PATCH] more byte conversion code and tests --- .idea/trevors_utilities.iml | 1 + src/bin/test.rs | 4 -- src/lib.rs | 1 + src/number_system_conversion.rs | 97 +++++++++++++++++++++++++++++++ tests/number_system_conversion.rs | 83 ++++++++++++++++++++++++++ 5 files changed, 182 insertions(+), 4 deletions(-) delete mode 100644 src/bin/test.rs create mode 100644 src/number_system_conversion.rs create mode 100644 tests/number_system_conversion.rs diff --git a/.idea/trevors_utilities.iml b/.idea/trevors_utilities.iml index cf84ae4..bbe0a70 100644 --- a/.idea/trevors_utilities.iml +++ b/.idea/trevors_utilities.iml @@ -3,6 +3,7 @@ + diff --git a/src/bin/test.rs b/src/bin/test.rs deleted file mode 100644 index 4009aba..0000000 --- a/src/bin/test.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("Taxation is Theft"); - println!("MANIFEST_DIR: {}", env!("CARGO_MANIFEST_DIR")); -} diff --git a/src/lib.rs b/src/lib.rs index 680618c..b15ba0c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ pub mod test_loader; pub mod test_compression; +pub mod number_system_conversion; diff --git a/src/number_system_conversion.rs b/src/number_system_conversion.rs new file mode 100644 index 0000000..9f3b6d6 --- /dev/null +++ b/src/number_system_conversion.rs @@ -0,0 +1,97 @@ +pub struct NumberSystemConversion {} + +impl NumberSystemConversion { + /// byte_to_bool + /// + /// Convert a u8 byte into a set of bool of the value + /// + /// ex: 0xff -> true, true, true, true, true, true, true, true + /// 0xa0 -> true, false, true, false, false, false, false, false + pub fn byte_to_bool(from: u8) -> [bool; 8] { + let mut return_values = [false; 8]; + for i in 0..8 { + let new_value = from >> i & 0x1 == 1; + return_values[i as usize] = new_value; + } + return_values + } + + /// bool_to_byte + /// + /// Convert a set of bool to a single byte + /// + /// ex: true, true, true, true, true, true, true, true -> 0xff + /// true, false, true, false, false, false, false, false -> 0xa0 + /// false, false, false, false, false, false, false, false -> 0x00 + pub fn bool_to_byte(from: [bool; 8]) -> u8 { + let mut return_value = 0u8; + for i in 0..from.len() { + let new_bit = 0x1 << i; + if from[i] { + return_value |= new_bit + } + } + return_value + } + + /// swap_endian_u16 + /// + /// Swaps endianness of a u16 + /// + /// ex: 0xabcd -> 0xcdab + /// 0x00ff -> 0xff00 + pub fn swap_endian_u16(from: u16) -> u16 { + // shift low to high and high to low + // merge the bits to a u16 + (from & 0xff) << 8 | (from & 0xff00) >> 8 + } + + /// Swap endian u32 + /// + /// Swaps endianness of a u32 + /// + /// ex. 0x12345678 -> 0x78563412 + pub fn swap_endian_u32(from: u32) -> u32 { + let mut bytes = vec![0, 0, 0, 0]; + // mask out what we want... + bytes[0] = from & 0x000000ff; + bytes[1] = (from & 0x0000ff00) >> 8; + bytes[2] = (from & 0x00ff0000) >> 16; + bytes[3] = (from & 0xff000000) >> 24; + // ...shift it into the right position + bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3] + } + + /// split_bytes_u16 + /// + /// Splits a u16 into its high and low bytes + /// + /// ex: 0xabcd -> 0xab, 0xcd + /// 0x0000 -> 0x00, 0x00 + /// 0xffff -> 0xff, 0xff + pub fn split_bytes_u16(from: u16) -> (u8, u8) { + let high = from.rotate_left(8) as u8; + let low = (from & 0xff) as u8; + + (high, low) + } + + /// join_bytes_u16 + pub fn join_bytes_u16(high: u16, low: u16) -> u16 { + low | high << 8 + } + + pub fn join_bytes_u16_from_u8(high: u8, low: u8) -> u16 { + low as u16 | ((high as u16) << 8) + } + + pub fn split_bytes_u32(from: u32) -> (u16, u16) { + let mut bytes = vec![]; + bytes[0] = (from & 0xffff) as u16; + bytes[1] = ((from & 0xffff0000) >> 16) as u16; + (bytes[0], bytes[1]) + } + pub fn split_bytes_u32_4(from: u32) -> (u8, u8, u8, u8) { + (0, 0, 0, 0) + } +} diff --git a/tests/number_system_conversion.rs b/tests/number_system_conversion.rs new file mode 100644 index 0000000..bb07ea0 --- /dev/null +++ b/tests/number_system_conversion.rs @@ -0,0 +1,83 @@ +use std::collections::BTreeMap; +use trevors_utilities::number_system_conversion::NumberSystemConversion; + +#[test] +fn byte_to_bool_and_bool_to_byte() { + // confirm a byte becomes a valid bool + // **** NOTE THAT THIS VISUALLY IS BACKWARDS AS INDEX 0 IS FIRST AND LSB IS LAST **** + let test_params: BTreeMap = BTreeMap::from([ + (0xff, [true, true, true, true, true, true, true, true]), + (0x00, [false, false, false, false, false, false, false, false]), + (0xa0, [false, false, false, false, false, true, false, true]) + ]); + + for (src, dst) in test_params { + assert_eq!( + dst, + NumberSystemConversion::byte_to_bool(src), + "Unable to convert [{}] to [{:?}]", src, dst + ); + assert_eq!( + src, + NumberSystemConversion::bool_to_byte(dst), + "Unable to convert [{:?}] to [{}]", dst, src + ); + assert_eq!( + src, + NumberSystemConversion::bool_to_byte( + NumberSystemConversion::byte_to_bool(src)) + ); + } +} + +#[test] +fn swap_endianness_u16() { + let test_params: Vec<(u16, u16)> = vec![(0xabcd, 0xcdab), (0x0000, 0x0000), (0xffff, 0xffff), (0x00ff, 0xff00)]; + + for (src, dst) in test_params { + assert_eq!(src, NumberSystemConversion::swap_endian_u16(dst)); + assert_eq!(src, NumberSystemConversion::swap_endian_u16(NumberSystemConversion::swap_endian_u16(src))); + assert_eq!(dst, NumberSystemConversion::swap_endian_u16(src)); + assert_eq!(dst, NumberSystemConversion::swap_endian_u16(NumberSystemConversion::swap_endian_u16(dst))); + } +} + +#[test] +fn swap_endinness_u32() { + let test_params: Vec<(u32, u32)> = vec![ + (0xabcdef01, 0x01efcdab), + (0x12345678, 0x78563412), + (0xbadbeef0, 0xf0eedbba) + ]; + + for (src, dst) in test_params { + assert_eq!(src, NumberSystemConversion::swap_endian_u32(dst)); + assert_eq!(src, NumberSystemConversion::swap_endian_u32( + NumberSystemConversion::swap_endian_u32(src))); + assert_eq!(dst, NumberSystemConversion::swap_endian_u32(src)); + assert_eq!(dst, NumberSystemConversion::swap_endian_u32( + NumberSystemConversion::swap_endian_u32(dst))); + } +} + +#[test] +fn split_bytes_u16_join_bytes_u16() { + let test_params = BTreeMap::from([ + (0x0000, (0x00, 0x00)), + (0xabcd, (0xab, 0xcd)), + (0xffff, (0xff, 0xff)), + (0xbeef, (0xbe, 0xef)) + ]); + + for (joined, (high, low)) in test_params { + assert_eq!( + (high, low), + NumberSystemConversion::split_bytes_u16(joined)); + assert_eq!( + joined, + NumberSystemConversion::join_bytes_u16_from_u8(high, low)); + assert_eq!( + joined, + NumberSystemConversion::join_bytes_u16(high as u16, low as u16)); + } +}