From 03e9484e526cd55265e9d38c22b3011745c03b70 Mon Sep 17 00:00:00 2001 From: Jason Travis Smith Date: Wed, 15 Feb 2017 17:51:13 -0500 Subject: [PATCH] Fixed the conversion code to use macros I wrote. The previous code was relying on the to_be and to_le functions from the standard library. These now rely on macros that I wrote to handle the bit packing and unpacking. These were macros and not functions because it is really hard to define the types and capabilities needed to turn them into general functions. As such, the macros should never be published publically and the Converters should be used for conversions. The Transmutable property should be used for serialization and internally the primitive types, Elements, all use the Converter functions and any other objects should use the Transmutable primitives to build their binary forms. --- Cargo.toml | 8 +- examples/convert_f32.rs | 8 +- examples/convert_quaternion.rs | 6 +- examples/convert_u16.rs | 7 +- examples/convert_vector2.rs | 6 +- src/converter.rs | 1 + src/endian.rs | 253 ++----- src/lib.rs | 3 + src/macros.rs | 136 ++++ src/transmutable.rs | 1175 +++++++++++++------------------- tests/converter.rs | 249 ------- tests/transmutable.rs | 92 --- 12 files changed, 684 insertions(+), 1260 deletions(-) create mode 100644 src/macros.rs delete mode 100644 tests/converter.rs delete mode 100644 tests/transmutable.rs diff --git a/Cargo.toml b/Cargo.toml index 9da9ea1..1f243cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,10 +13,12 @@ keywords = ["converter", "binary"] default = [] convert_sigils = ["sigils"] -[dependencies] -scribe = { git = "https://gitlab.com/CyberMages/scribe.git" } +[dependencies.scribe] +git = "https://gitlab.com/CyberMages/scribe.git" -sigils = { optional = true, git = "https://gitlab.com/CyberMages/sigils.git" } +[dependencies.sigils] +optional = true +git = "https://gitlab.com/CyberMages/sigils.git" [dev-dependencies] rand = { version = "*" } diff --git a/examples/convert_f32.rs b/examples/convert_f32.rs index f9dce31..6bcf749 100644 --- a/examples/convert_f32.rs +++ b/examples/convert_f32.rs @@ -1,9 +1,7 @@ -#![feature(convert)] - extern crate alchemy; -use alchemy::F32_BYTES; + use alchemy::{Converter, Endianess, PlatformEndian, Transmutable}; @@ -47,12 +45,12 @@ pub fn use_transmutable() println!("Buffer starts as: {}", stringify_array(buffer.as_slice())); // Convert the floating point number into an array of bytes. - buffer = num.to_bytes(endianess); + buffer = num.as_endian_bytes(endianess); println!("Buffer contains: {}", stringify_array(buffer.as_slice())); // Convert the array of bytes into a floating point number. - final_num = f32::from_bytes(buffer.as_slice(), endianess); + final_num = f32::from_endian_bytes(buffer.as_slice(), endianess); println!("The buffer converts back to: {}", final_num); } diff --git a/examples/convert_quaternion.rs b/examples/convert_quaternion.rs index 2cf1f1a..1dfaf30 100644 --- a/examples/convert_quaternion.rs +++ b/examples/convert_quaternion.rs @@ -65,7 +65,7 @@ pub fn main() // Initialize the variables. quat = Quaternion::::from_values(6.29f64, 1.9f64, 8.5f64, 7.11f64); buffer = Vec::with_capacity(SIZE_OF_QUATERNION); - endianess = Endianess::PLATFORM; + endianess = Endianess::Platform; println!("Transmuting a Quaternion:"); @@ -74,11 +74,11 @@ pub fn main() println!("Buffer starts as: {}", stringify_array(buffer.as_slice())); // Convert the Vector2 into an array of bytes. - buffer = quat.to_bytes(endianess); + buffer = quat.as_endian_bytes(endianess); println!("Buffer contains: {}", stringify_array(buffer.as_slice())); // Convert the array of bytes into a Vector2. - final_quat = Quaternion::from_bytes(buffer.as_slice(), endianess); + final_quat = Quaternion::from_endian_bytes(buffer.as_slice(), endianess); println!("The buffer converts back to: {}", final_quat); } diff --git a/examples/convert_u16.rs b/examples/convert_u16.rs index f81c3de..e315815 100644 --- a/examples/convert_u16.rs +++ b/examples/convert_u16.rs @@ -1,9 +1,6 @@ -#![feature(convert)] - extern crate alchemy; -use alchemy::U16_BYTES; use alchemy::{Converter, Endianess, PlatformEndian, Transmutable}; use alchemy::platform_to_network_order; @@ -48,12 +45,12 @@ pub fn use_transmutable() println!("Buffer starts as: {}", stringify_array(buffer.as_slice())); // Convert the short point number into an array of bytes. - buffer = num.to_bytes(endianess); + buffer = num.as_endian_bytes(endianess); println!("Buffer contains: {}", stringify_array(buffer.as_slice())); // Convert the array of bytes into a short number. - final_num = u16::from_bytes(buffer.as_slice(), endianess); + final_num = u16::from_endian_bytes(buffer.as_slice(), endianess); println!("The buffer converts back to: {}", final_num); } diff --git a/examples/convert_vector2.rs b/examples/convert_vector2.rs index 0ecafa8..b742c03 100644 --- a/examples/convert_vector2.rs +++ b/examples/convert_vector2.rs @@ -65,7 +65,7 @@ pub fn main() // Initialize the variables. vec = Vector2::::new(629u64, 1985u64); buffer = Vec::with_capacity(SIZE_OF_VECTOR_2); - endianess = Endianess::PLATFORM; + endianess = Endianess::Platform; println!("Transmuting a Vector2:"); @@ -74,11 +74,11 @@ pub fn main() println!("Buffer starts as: {}", stringify_array(buffer.as_slice())); // Convert the Vector2 into an array of bytes. - buffer = vec.to_bytes(endianess); + buffer = vec.as_endian_bytes(endianess); println!("Buffer contains: {}", stringify_array(buffer.as_slice())); // Convert the array of bytes into a Vector2. - final_vec = Vector2::from_bytes(buffer.as_slice(), endianess); + final_vec = Vector2::from_endian_bytes(buffer.as_slice(), endianess); println!("The buffer converts back to: {}", final_vec); } diff --git a/src/converter.rs b/src/converter.rs index b6e68be..a34a986 100644 --- a/src/converter.rs +++ b/src/converter.rs @@ -254,6 +254,7 @@ pub trait Converter } + /// Switches an unsigned value into its signed equivalent. /// /// NOTE: This seems messy for larger unsigned values. diff --git a/src/endian.rs b/src/endian.rs index cd4a7cf..6f78ae2 100644 --- a/src/endian.rs +++ b/src/endian.rs @@ -1,8 +1,5 @@ -use std::mem; -use std::ptr::copy_nonoverlapping; - use ::byte_sized::ByteSized; -use ::byte_sized::{U16_BYTES, U32_BYTES, U64_BYTES}; +use ::byte_sized::U64_BYTES; use ::converter::Converter; use ::transmutable::Transmutable; @@ -112,108 +109,63 @@ impl Converter for BigEndian { fn bytes_to_u16(buffer: &[u8]) -> u16 { - read_bytes!(buffer, u16, to_be) + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == u16::BYTES); + + pack_big_endian!(buffer, u16, u16::BYTES) } fn bytes_to_u32(buffer: &[u8]) -> u32 { - read_bytes!(buffer, u32, to_be) + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == u32::BYTES); + + pack_big_endian!(buffer, u32, u32::BYTES) } fn bytes_to_u64(buffer: &[u8]) -> u64 { - read_bytes!(buffer, u64, to_be) + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == u64::BYTES); + + pack_big_endian!(buffer, u64, u64::BYTES) } fn bytes_to_usize(buffer: &[u8]) -> usize { - let mut out: [u8; 8]; - let ptr_out: *mut u8; + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == usize::BYTES); - assert!(buffer.len() >= 1 && buffer.len() <= 8); - - out = [0u8; 8]; - ptr_out = out.as_mut_ptr(); - unsafe - { - copy_nonoverlapping::(buffer.as_ptr(), - ptr_out.offset((8 - buffer.len()) as isize), - buffer.len()); - - (*(ptr_out as *const u64)).to_be() as usize - } + pack_big_endian!(buffer, usize, usize::BYTES) } fn u16_to_bytes(num: u16) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u16::BYTES); - - // Write the bytes to the Vector. - write_bytes!(buffer, u16, U16_BYTES, num, to_be); - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_big_endian!(num, u16::BYTES) } fn u32_to_bytes(num: u32) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u32::BYTES); - - // Write the bytes to the Vector. - write_bytes!(buffer, u32, U32_BYTES, num, to_be); - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_big_endian!(num, u32::BYTES) } fn u64_to_bytes(num: u64) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u64::BYTES); - - // Write the bytes to the Vector. - write_bytes!(buffer, u64, U64_BYTES, num, to_be); - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_big_endian!(num, u64::BYTES) } fn usize_to_bytes(num: usize) -> Vec { - let bytes: [u8; 8]; - let num_bytes: u8; - let mut buffer: Vec; - - num_bytes = usize::BYTES as u8; - - // Create a buffer with enough space for this type. - buffer = Vec::with_capacity(usize::BYTES); - - assert!(determine_size(num as u64) <= num_bytes && num_bytes <= 8); - - unsafe - { - bytes = mem::transmute::(num.to_be()); - buffer.extend_from_slice(&bytes); - //copy_nonoverlapping::( - // bytes.as_ptr().offset((8 - num_bytes) as isize), - // buffer.as_mut_ptr(), num_bytes as usize); - } - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_big_endian!(num, usize::BYTES) } fn bytes_to_string(buffer: &[u8]) -> String @@ -285,104 +237,63 @@ impl Converter for LittleEndian { fn bytes_to_u16(buffer: &[u8]) -> u16 { - read_bytes!(buffer, u16, to_le) + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == u16::BYTES); + + pack_little_endian!(buffer, u16, u16::BYTES) } fn bytes_to_u32(buffer: &[u8]) -> u32 { - read_bytes!(buffer, u32, to_le) + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == u32::BYTES); + + pack_little_endian!(buffer, u32, u32::BYTES) } fn bytes_to_u64(buffer: &[u8]) -> u64 { - read_bytes!(buffer, u64, to_le) + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == u64::BYTES); + + pack_little_endian!(buffer, u64, u64::BYTES) } fn bytes_to_usize(buffer: &[u8]) -> usize { - let mut out: [u8; 8]; - let ptr_out: *mut u8; + // Make sure that there is enough space to read + // a value from the buffer. + assert!(buffer.len() == usize::BYTES); - assert!(buffer.len() >= 1 && buffer.len() <= 8); - - out = [0u8; 8]; - ptr_out = out.as_mut_ptr(); - unsafe - { - copy_nonoverlapping::(buffer.as_ptr(), ptr_out, buffer.len()); - (*(ptr_out as *const u64)).to_le() as usize - } + pack_little_endian!(buffer, usize, usize::BYTES) } fn u16_to_bytes(num: u16) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u16::BYTES); - - // Write the bytes to the Vector. - write_bytes!(buffer, u16, U16_BYTES, num, to_le); - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_little_endian!(num, u16::BYTES) } fn u32_to_bytes(num: u32) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u32::BYTES); - - // Write the bytes to the Vector. - write_bytes!(buffer, u32, U32_BYTES, num, to_le); - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_little_endian!(num, u32::BYTES) } fn u64_to_bytes(num: u64) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u64::BYTES); - - // Write the bytes to the Vector. - write_bytes!(buffer, u64, U64_BYTES, num, to_le); - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_little_endian!(num, u64::BYTES) } fn usize_to_bytes(num: usize) -> Vec { - let bytes: [u8; 8]; - let num_bytes: u8; - let mut buffer: Vec; - - num_bytes = usize::BYTES as u8; - - // Create a buffer with enough space for this type. - buffer = Vec::with_capacity(usize::BYTES); - - assert!(determine_size(num as u64) <= num_bytes && num_bytes <= 8); - - unsafe - { - bytes = mem::transmute::(num.to_le()); - buffer.extend_from_slice(&bytes); - //copy_nonoverlapping::(bytes.as_ptr(), buffer.as_mut_ptr(), - // num_bytes as usize); - } - - // Return the byte buffer. - buffer + // Unpack the value into it's byte form. + unpack_little_endian!(num, usize::BYTES) } fn bytes_to_string(buffer: &[u8]) -> String @@ -396,7 +307,7 @@ impl Converter for LittleEndian // Strings start with the size of bytes to read as // a u64. So read that in and then we know how many // bytes make up the string. - byte_count = BigEndian::bytes_to_u64(&buffer[0..U64_BYTES]); + byte_count = LittleEndian::bytes_to_u64(&buffer[0..U64_BYTES]); if byte_count > 0 { @@ -493,8 +404,6 @@ impl ::std::fmt::Display for Endianess pub fn network_to_platform_order(val: T) -> T where T: Transmutable { - let buffer: Vec; - // Determine what endianess the Platform is using. if cfg!(target_endian="big") { @@ -504,9 +413,7 @@ pub fn network_to_platform_order(val: T) -> T } else { - // Convert the value from Big endian to Little endian. - buffer = val.as_endian_bytes(Endianess::Network); - T::from_endian_bytes(buffer.as_slice(), Endianess::Platform) + T::from_endian_bytes(val.as_bytes().as_slice(), Endianess::Platform) } } @@ -514,8 +421,6 @@ pub fn network_to_platform_order(val: T) -> T pub fn platform_to_network_order(val: T) -> T where T: Transmutable { - let buffer: Vec; - // Determine what endianess the Platform is using. if cfg!(target_endian="big") { @@ -525,9 +430,7 @@ pub fn platform_to_network_order(val: T) -> T } else { - // Convert the value from Little endian to Big endian. - buffer = val.as_endian_bytes(Endianess::Platform); - T::from_endian_bytes(buffer.as_slice(), Endianess::Network) + T::from_endian_bytes(val.as_bytes().as_slice(), Endianess::Platform) } } @@ -549,43 +452,3 @@ pub fn get_platform_endianess() -> Endianess Endianess::Little } } - - - -/// Determine the amount of bytes required to -/// represent the given number. -fn determine_size(num: u64) -> u8 -{ - if num < (1 << 8) - { - 1 - } - else if num < (1 << 16) - { - 2 - } - else if num < (1 << 24) - { - 3 - } - else if num < (1 << 32) - { - 4 - } - else if num < (1 << 40) - { - 5 - } - else if num < (1 << 48) - { - 6 - } - else if num < (1 << 56) - { - 7 - } - else - { - 8 - } -} diff --git a/src/lib.rs b/src/lib.rs index e726316..3749638 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,9 @@ extern crate sigils; +#[macro_use] +mod macros; + mod byte_sized; mod converter; mod endian; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..2eb66ed --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,136 @@ +//! Macros were created because functions started to get really complicated. +//! These macros should not be exported out of the library as they are +//! not safe to use since they do no type checking. + + + +/// Handles the repetative bit packing for big endian. +macro_rules! pack_big_endian +{ + ($buffer: ident, $target_type: ty, $bytes: expr) => + { + { + let mut value: $target_type; + + // Make sure that there is enough data to read + // the bytes for this type. + assert!($buffer.len() >= $bytes); + + // Start with a value of zero and or it with + // the bits shifted values from the buffer. + value = 0; + for i in 0..$bytes + { + value |= ($buffer[i] as $target_type) << ((($bytes - i) - 1) * 8); + } + + // Return the determined value. + value + } + } +} + +/// Handles the repetative bit packing for little endian. +macro_rules! pack_little_endian +{ + ($buffer: ident, $target_type: ty, $bytes: expr) => + { + { + let mut value: $target_type; + + // Make sure that there is enough data to read + // the bytes for this type. + assert!($buffer.len() >= $bytes); + + // Start with a value of zero and or it with + // the bits shifted values from the buffer. + value = 0; + for i in 0..$bytes + { + value |= ($buffer[($bytes - 1) - i] as $target_type) << + ((($bytes - i) - 1) * 8); + } + + // Return the determined value. + value + } + } +} + +/// Handles the repetative big endian unpacking. +macro_rules! unpack_big_endian +{ + ($value: expr, $bytes: expr) => + { + { + let mut buffer: Vec; + + // Create an array with enough space for this value + // and then bit shift the value into a buffer of bytes. + buffer = Vec::with_capacity($bytes); + for i in 0..$bytes + { + buffer.push(($value >> (($bytes - i) - 1) * 8) as u8); + } + + // Return the buffer of bytes that represent this value. + buffer + } + } +} + +/// Handles the repetative little endian unpacking. +macro_rules! unpack_little_endian +{ + ($value: expr, $bytes: expr) => + { + { + let mut buffer: Vec; + + // Create an array with enough space for this value + // and then bit shift the value into a buffer of bytes. + buffer = Vec::with_capacity($bytes); + for i in 0..$bytes + { + buffer.push(($value >> (i * 8)) as u8); + } + + // Return the buffer of bytes that represent this value. + buffer + } + } +} + +/// Handles swapping from big endian to little endian. +macro_rules! swap_big_to_little_endian +{ + ($value: expr, $target_type: ty, $bytes: expr) => + { + { + let buffer: Vec; + + // Convert the big endian value to bytes. + buffer = unpack_big_endian!($value, $bytes); + + // Convert the buffer of bytes to a little endian value. + pack_little_endian!(buffer, $target_type, $bytes) + } + } +} + +/// Handles swapping from little endian to big endian. +macro_rules! swap_little_to_big_endian +{ + ($value: expr, $target_type: ty, $bytes: expr) => + { + { + let buffer: Vec; + + // Convert the little endian value to bytes. + buffer = unpack_little_endian!($value, $bytes); + + // Convert the buffer of bytes to a big endian value. + pack_big_endian!(buffer, $target_type, $bytes) + } + } +} diff --git a/src/transmutable.rs b/src/transmutable.rs index 87b257f..aa71ee2 100644 --- a/src/transmutable.rs +++ b/src/transmutable.rs @@ -1,7 +1,9 @@ #[cfg(feature="convert_sigils")] use sigils::{Zero, Number, Real}; + #[cfg(feature="convert_sigils")] use sigils::vector::{Vector, Vector2, Vector3, Vector4}; + #[cfg(feature="convert_sigils")] use sigils::quaternion::Quaternion; @@ -17,18 +19,33 @@ use ::endian::Endianess; /// A type that can be converted to and from bytes. pub trait Transmutable { - /// Transmute this type to an array of bytes. - fn as_bytes(&self) -> Vec; - - /// Transmute this type to an array of bytes. - fn as_endian_bytes(&self, endianess: Endianess) -> Vec; - - /// Transmute an array of bytes to this type. + /// Transmute an array of bytes in the + /// platform's endian to this type. fn from_bytes(buffer: &[u8]) -> Self; - /// Transmute an array of bytes to this type. + /// Transmute an array of bytes in the + /// given endian to this type. fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self; + + /// Transmute this type to an array of bytes in + /// the Platform's endian. + fn to_bytes(self) -> Vec; + + /// Transmute this type to an array of bytes in + /// the desired endian. + fn to_endian_bytes(self, endianess: Endianess) -> Vec; + + + /// Transmute this type to an array of bytes in + /// the Platform's endian. + fn as_bytes(&self) -> Vec; + + /// Transmute this type to an array of bytes in + /// the desired endian. + fn as_endian_bytes(&self, endianess: Endianess) -> Vec; + + /// Get the current size of this Transmutable in bytes. fn determine_byte_size(&self) -> usize; } @@ -40,29 +57,29 @@ pub trait Transmutable /// a number to bytes. macro_rules! handle_endianess_to_bytes { - ($buffer: ident, $val: ident, $endianess: ident, $func: ident) => + ($val: ident, $endianess: ident, $func: ident) => { { match $endianess { Endianess::Big => { - $buffer.append(&mut BigEndian::$func(*$val)); + BigEndian::$func(*$val) } Endianess::Little => { - $buffer.append(&mut LittleEndian::$func(*$val)); + LittleEndian::$func(*$val) } Endianess::Platform => { - $buffer.append(&mut PlatformEndian::$func(*$val)); + PlatformEndian::$func(*$val) } Endianess::Network => { - $buffer.append(&mut NetworkEndian::$func(*$val)); + NetworkEndian::$func(*$val) } } } @@ -101,99 +118,49 @@ macro_rules! handle_endianess_from_bytes } } -/// Handles the repetative bit packing. -macro_rules! pack_bits -{ - ($buffer: ident, $target_type: ty, $bytes: expr) => - { - { - let mut value: $target_type; - - // Make sure that there is enough data to read - // the bytes for this type. - assert!($buffer.len() >= $bytes); - - // Start with a value of zero and or it with - // the bits shifted values from the buffer. - value = 0; - for i in 0..$bytes - { - value |= ($buffer[i] as $target_type) << ((($bytes - i) - 1) * 8); - } - - // Return the determined value. - value - } - } -} - -/// Handles the repetative bit unpacking. -macro_rules! unpack_bits -{ - ($value: expr, $bytes: expr) => - { - { - let mut buffer: Vec; - - // Create an array with enough space for this value - // and then bit shift the value into a buffer of bytes. - buffer = Vec::with_capacity($bytes); - for i in 0..$bytes - { - buffer.push(($value >> (($bytes - i) - 1) * 8) as u8); - } - - // Return the buffer of bytes that represent this value. - buffer - } - } -} - impl Transmutable for u8 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, u8::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } #[allow(unused_variables)] - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the byte. - buffer = Vec::with_capacity(u8::BYTES); - - // Convert this to bytes and add it to the buffer. - // Endianess doesn't matter here. - buffer.push(*self); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> u8 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, u8, u8::BYTES) - } - - #[allow(unused_variables)] - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> u8 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= u8::BYTES); - // Convert the given bytes to this type and return it. - // Endianess doesn't matter here. + // Just return the byte from the buffer. + // A single byte has no endian form. buffer[0] } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + #[allow(unused_variables)] + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // A single byte has no endian form. + vec![*self] + } + fn determine_byte_size(&self) -> usize { u8::BYTES @@ -202,35 +169,12 @@ impl Transmutable for u8 impl Transmutable for u16 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, u16::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u16::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, u16_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> u16 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, u16, u16::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> u16 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -240,6 +184,27 @@ impl Transmutable for u16 handle_endianess_from_bytes!(buffer, endianess, bytes_to_u16) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Return the Endianess conversion. + handle_endianess_to_bytes!(self, endianess, u16_to_bytes) + } + fn determine_byte_size(&self) -> usize { u16::BYTES @@ -248,35 +213,12 @@ impl Transmutable for u16 impl Transmutable for u32 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, u32::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u32::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, u32_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> u32 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, u32, u32::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> u32 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -286,6 +228,27 @@ impl Transmutable for u32 handle_endianess_from_bytes!(buffer, endianess, bytes_to_u32) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Convert this to bytes and add it to the buffer. + handle_endianess_to_bytes!(self, endianess, u32_to_bytes) + } + fn determine_byte_size(&self) -> usize { u32::BYTES @@ -294,35 +257,12 @@ impl Transmutable for u32 impl Transmutable for u64 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, u64::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(u64::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, u64_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> u64 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, u64, u64::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> u64 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -332,6 +272,27 @@ impl Transmutable for u64 handle_endianess_from_bytes!(buffer, endianess, bytes_to_u64) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Convert this to bytes and add it to the buffer. + handle_endianess_to_bytes!(self, endianess, u64_to_bytes) + } + fn determine_byte_size(&self) -> usize { u64::BYTES @@ -340,35 +301,12 @@ impl Transmutable for u64 impl Transmutable for usize { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, usize::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(usize::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, usize_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> usize - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, usize, usize::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> usize + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -378,6 +316,27 @@ impl Transmutable for usize handle_endianess_from_bytes!(buffer, endianess, bytes_to_usize) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Convert this to bytes and add it to the buffer. + handle_endianess_to_bytes!(self, endianess, usize_to_bytes) + } + fn determine_byte_size(&self) -> usize { usize::BYTES @@ -386,47 +345,42 @@ impl Transmutable for usize impl Transmutable for i8 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, i8::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } #[allow(unused_variables)] - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(i8::BYTES); - - // Convert this to bytes and add it to the buffer. - buffer.push(*self as u8); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> i8 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, i8, i8::BYTES) - } - - #[allow(unused_variables)] - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> i8 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= i8::BYTES); - // Convert the given bytes to this type and return it. - // Endianess doesn't matter here. buffer[0] as i8 } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + #[allow(unused_variables)] + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + vec![*self as u8] + } + fn determine_byte_size(&self) -> usize { i8::BYTES @@ -435,35 +389,12 @@ impl Transmutable for i8 impl Transmutable for i16 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, i16::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(i16::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, i16_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> i16 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, i16, i16::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> i16 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -473,6 +404,27 @@ impl Transmutable for i16 handle_endianess_from_bytes!(buffer, endianess, bytes_to_i16) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Convert this to bytes and add it to the buffer. + handle_endianess_to_bytes!(self, endianess, i16_to_bytes) + } + fn determine_byte_size(&self) -> usize { i16::BYTES @@ -481,35 +433,12 @@ impl Transmutable for i16 impl Transmutable for i32 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, i32::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(i32::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, i32_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> i32 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, i32, i32::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> i32 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -519,6 +448,27 @@ impl Transmutable for i32 handle_endianess_from_bytes!(buffer, endianess, bytes_to_i32) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Convert this to bytes and add it to the buffer. + handle_endianess_to_bytes!(self, endianess, i32_to_bytes) + } + fn determine_byte_size(&self) -> usize { i32::BYTES @@ -527,35 +477,12 @@ impl Transmutable for i32 impl Transmutable for i64 { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, i64::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(i64::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, i64_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> i64 - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, i64, i64::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> i64 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -565,6 +492,27 @@ impl Transmutable for i64 handle_endianess_from_bytes!(buffer, endianess, bytes_to_i64) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Convert this to bytes and add it to the buffer. + handle_endianess_to_bytes!(self, endianess, i64_to_bytes) + } + fn determine_byte_size(&self) -> usize { i64::BYTES @@ -573,35 +521,12 @@ impl Transmutable for i64 impl Transmutable for isize { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - // Unpack the bits that make up this value and - // return a buffer of the bytes. - unpack_bits!(*self, isize::BYTES) + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(isize::BYTES); - - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, isize_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> isize - { - // Convert the given bytes to this type and return it. - pack_bits!(buffer, isize, isize::BYTES) - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> isize + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { // Make sure that there is enough data to read // the bytes for this type. @@ -611,6 +536,27 @@ impl Transmutable for isize handle_endianess_from_bytes!(buffer, endianess, bytes_to_isize) } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + // Convert this to bytes and add it to the buffer. + handle_endianess_to_bytes!(self, endianess, isize_to_bytes) + } + fn determine_byte_size(&self) -> usize { isize::BYTES @@ -619,49 +565,40 @@ impl Transmutable for isize impl Transmutable for f32 { + fn from_bytes(buffer: &[u8]) -> Self + { + Self::from_endian_bytes(buffer, Endianess::Platform) + } + + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self + { + // Make sure that there is enough data to read + // the bytes for this type. + assert!(buffer.len() >= f32::BYTES); + + // Convert the given bytes to this type and return it. + handle_endianess_from_bytes!(buffer, endianess, bytes_to_f32) + } + + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + fn as_bytes(&self) -> Vec { - let value: u32; - - unsafe - { - value = ::std::mem::transmute::(*self); - } - - value.as_bytes() + self.as_endian_bytes(Endianess::Platform) } fn as_endian_bytes(&self, endianess: Endianess) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(f32::BYTES); - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, f32_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> f32 - { - unsafe - { - ::std::mem::transmute::(u32::from_bytes(buffer)) - } - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> f32 - { - // Make sure that there is enough data to read - // the bytes for this type. - assert!(buffer.len() >= 4); - - // Convert the given bytes to this type and return it. - handle_endianess_from_bytes!(buffer, endianess, bytes_to_f32) + handle_endianess_to_bytes!(self, endianess, f32_to_bytes) } fn determine_byte_size(&self) -> usize @@ -672,49 +609,40 @@ impl Transmutable for f32 impl Transmutable for f64 { + fn from_bytes(buffer: &[u8]) -> Self + { + Self::from_endian_bytes(buffer, Endianess::Platform) + } + + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self + { + // Make sure that there is enough data to read + // the bytes for this type. + assert!(buffer.len() >= f64::BYTES); + + // Convert the given bytes to this type and return it. + handle_endianess_from_bytes!(buffer, endianess, bytes_to_f64) + } + + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + fn as_bytes(&self) -> Vec { - let value: u64; - - unsafe - { - value = ::std::mem::transmute::(*self); - } - - value.as_bytes() + self.as_endian_bytes(Endianess::Platform) } fn as_endian_bytes(&self, endianess: Endianess) -> Vec { - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(f64::BYTES); - // Convert this to bytes and add it to the buffer. - handle_endianess_to_bytes!(buffer, self, endianess, f64_to_bytes); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> f64 - { - unsafe - { - ::std::mem::transmute::(u64::from_bytes(buffer)) - } - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> f64 - { - // Make sure that there is enough data to read - // the bytes for this type. - assert!(buffer.len() >= 8); - - // Convert the given bytes to this type and return it. - handle_endianess_from_bytes!(buffer, endianess, bytes_to_f64) + handle_endianess_to_bytes!(self, endianess, f64_to_bytes) } fn determine_byte_size(&self) -> usize @@ -725,114 +653,58 @@ impl Transmutable for f64 impl Transmutable for String { + fn from_bytes(buffer: &[u8]) -> Self + { + Self::from_endian_bytes(buffer, Endianess::Platform) + } + + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self + { + // Convert the given bytes to this type and return it. + handle_endianess_from_bytes!(buffer, endianess, bytes_to_string) + } + + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + fn as_bytes(&self) -> Vec { - let bytes: &[u8]; - let byte_count: u64; - let mut buffer: Vec; - - // Turn the string into a byte array. - bytes = self.as_bytes(); - - // Determine how many bytes will be written - // for this string. - byte_count = bytes.len() as u64; - - // Make sure the buffer has enough space for this string. - buffer = Vec::with_capacity(bytes.len() + u64::BYTES); - - // Add the count to the buffer. - buffer.append(&mut byte_count.as_bytes()); - - // Add each byte of the string to the buffer. - buffer.extend_from_slice(bytes); - - // Return the byte buffer. - buffer + self.as_endian_bytes(Endianess::Platform) } fn as_endian_bytes(&self, endianess: Endianess) -> Vec { - let temp: String; - let mut buffer: Vec; - - // Create the Vector to hold the bytes - // from this type. - buffer = Vec::with_capacity(get_byte_size_of_string(self)); - - // Clone the string so that we can use its data. - // We have to do this because Strings don't implement Copy. - temp = self.clone(); - // Convert this to bytes and add it to the buffer. // We are not using the macro because *String is a str. match endianess { Endianess::Big => { - buffer.append(&mut BigEndian::string_to_bytes(temp)); + BigEndian::string_to_bytes(self.clone()) } Endianess::Little => { - buffer.append(&mut LittleEndian::string_to_bytes(temp)); + LittleEndian::string_to_bytes(self.clone()) } Endianess::Platform => { - buffer.append(&mut PlatformEndian::string_to_bytes(temp)); + PlatformEndian::string_to_bytes(self.clone()) } Endianess::Network => { - buffer.append(&mut NetworkEndian::string_to_bytes(temp)); + NetworkEndian::string_to_bytes(self.clone()) } } - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> String - { - let byte_count: u64; - let new_string: String; - - // A string array should have atleast a u64 size byte count. - assert!(buffer.len() >= u64::BYTES); - - // Strings start with the size of bytes to read as - // a u64. So read that in and then we know how many - // bytes make up the string. - byte_count = u64::from_bytes(&buffer[0..u64::BYTES]); - - if byte_count > 0 - { - match String::from_utf8(buffer[u64::BYTES..(buffer.len()-1)].to_vec()) - { - Ok(string) => - { - new_string = string; - } - - Err(error) => - { - error!("{}", error); - } - } - } - else - { - new_string = String::new(); - } - - new_string - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> String - { - // Convert the given bytes to this type and return it. - handle_endianess_from_bytes!(buffer, endianess, bytes_to_string) } fn determine_byte_size(&self) -> usize @@ -844,75 +716,12 @@ impl Transmutable for String #[cfg(feature="convert_sigils")] impl Transmutable for Vector2 where T: Number + ByteSized + Transmutable { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self { - let byte_size: usize; - let num_bytes: usize; - let mut buffer: Vec; - - // Determine the number of bytes requires to - // represent a Vector2. - byte_size = T::get_byte_size(); - num_bytes = byte_size * self.get_size() as usize; - - // Make sure that there is enough space to store - // the bytes from this type. - buffer = Vec::with_capacity(num_bytes); - - // Convert this to bytes and add it to the buffer. - buffer.append(&mut self.x.as_bytes()); - buffer.append(&mut self.y.as_bytes()); - - // Return the byte buffer. - buffer + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let byte_size: usize; - let num_bytes: usize; - let mut buffer: Vec; - - // Determine the number of bytes requires to - // represent a Vector2. - byte_size = T::get_byte_size(); - num_bytes = byte_size * self.get_size() as usize; - - // Make sure that there is enough space to store - // the bytes from this type. - buffer = Vec::with_capacity(num_bytes); - - // Convert this to bytes and add it to the buffer. - buffer.append(&mut self.x.as_endian_bytes(endianess)); - buffer.append(&mut self.y.as_endian_bytes(endianess)); - - // Return the byte buffer. - buffer - } - - fn from_bytes(buffer: &[u8]) -> Vector2 - { - let byte_size: usize; - let num_bytes: usize; - let mut vec: Vector2; - - // Determine the number of bytes requires to - // represent a Vector2. - vec = Vector2::::zero(); - byte_size = T::get_byte_size(); - num_bytes = byte_size * vec.get_size() as usize; - - // Make sure that there is enough data to read - // the bytes for this type. - assert!(buffer.len() >= num_bytes); - - // Convert the given bytes to this type and return it. - vec.x = T::from_bytes(&buffer[0..byte_size]); - vec.y = T::from_bytes(&buffer[byte_size..num_bytes]); - vec - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Vector2 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { let byte_size: usize; let num_bytes: usize; @@ -936,16 +745,22 @@ impl Transmutable for Vector2 where T: Number + ByteSized + Transmutable vec } - fn determine_byte_size(&self) -> usize + fn to_bytes(self) -> Vec { - T::get_byte_size() * self.get_size() as usize + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) } -} -#[cfg(feature="convert_sigils")] -impl Transmutable for Vector3 where T: Number + ByteSized + Transmutable -{ fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec { let byte_size: usize; let num_bytes: usize; @@ -960,63 +775,29 @@ impl Transmutable for Vector3 where T: Number + ByteSized + Transmutable // the bytes from this type. buffer = Vec::with_capacity(num_bytes); - // Convert this to bytes and add it to the buffer. - buffer.append(&mut self.x.as_bytes()); - buffer.append(&mut self.y.as_bytes()); - buffer.append(&mut self.z.as_bytes()); - - // Return the byte buffer. - buffer - } - - fn as_endian_bytes(&self, endianess: Endianess) -> Vec - { - let byte_size: usize; - let num_bytes: usize; - let mut buffer: Vec; - - // Determine the number of bytes requires to - // represent a Vector3. - byte_size = T::get_byte_size(); - num_bytes = byte_size * self.get_size() as usize; - - // Make sure that there is enough space to store - // the bytes from this type. - buffer = Vec::with_capacity(num_bytes); - // Convert this to bytes and add it to the buffer. buffer.append(&mut self.x.as_endian_bytes(endianess)); buffer.append(&mut self.y.as_endian_bytes(endianess)); - buffer.append(&mut self.z.as_endian_bytes(endianess)); // Return the byte buffer. buffer } - fn from_bytes(buffer: &[u8]) -> Vector3 + fn determine_byte_size(&self) -> usize { - let byte_size: usize; - let num_bytes: usize; - let mut vec: Vector3; + T::get_byte_size() * self.get_size() as usize + } +} - // Determine the number of bytes requires to - // represent a Vector3. - vec = Vector3::::zero(); - byte_size = T::get_byte_size(); - num_bytes = byte_size * vec.get_size() as usize; - - // Make sure that there is enough data to read - // the bytes for this type. - assert!(buffer.len() >= num_bytes); - - // Convert the given bytes to this type and return it. - vec.x = T::from_bytes(&buffer[0..byte_size]); - vec.y = T::from_bytes(&buffer[byte_size..(byte_size*2)]); - vec.z = T::from_bytes(&buffer[(byte_size*2)..num_bytes]); - vec +#[cfg(feature="convert_sigils")] +impl Transmutable for Vector3 where T: Number + ByteSized + Transmutable +{ + fn from_bytes(buffer: &[u8]) -> Self + { + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Vector3 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { let byte_size: usize; let num_bytes: usize; @@ -1042,38 +823,19 @@ impl Transmutable for Vector3 where T: Number + ByteSized + Transmutable vec } - fn determine_byte_size(&self) -> usize + fn to_bytes(self) -> Vec { - T::get_byte_size() * self.get_size() as usize + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) } -} -#[cfg(feature="convert_sigils")] -impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable -{ fn as_bytes(&self) -> Vec { - let byte_size: usize; - let num_bytes: usize; - let mut buffer: Vec; - - // Determine the number of bytes requires to - // represent a Vector4. - byte_size = T::get_byte_size(); - num_bytes = byte_size * self.get_size() as usize; - - // Make sure that there is enough space to store - // the bytes from this type. - buffer = Vec::with_capacity(num_bytes); - - // Convert this to bytes and add it to the buffer. - buffer.append(&mut self.x.as_bytes()); - buffer.append(&mut self.y.as_bytes()); - buffer.append(&mut self.z.as_bytes()); - buffer.append(&mut self.w.as_bytes()); - - // Return the byte buffer. - buffer + self.as_endian_bytes(Endianess::Platform) } fn as_endian_bytes(&self, endianess: Endianess) -> Vec @@ -1083,7 +845,7 @@ impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable let mut buffer: Vec; // Determine the number of bytes requires to - // represent a Vector4. + // represent a Vector3. byte_size = T::get_byte_size(); num_bytes = byte_size * self.get_size() as usize; @@ -1095,37 +857,26 @@ impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable buffer.append(&mut self.x.as_endian_bytes(endianess)); buffer.append(&mut self.y.as_endian_bytes(endianess)); buffer.append(&mut self.z.as_endian_bytes(endianess)); - buffer.append(&mut self.w.as_endian_bytes(endianess)); // Return the byte buffer. buffer } - fn from_bytes(buffer: &[u8]) -> Vector4 + fn determine_byte_size(&self) -> usize { - let byte_size: usize; - let num_bytes: usize; - let mut vec: Vector4; + T::get_byte_size() * self.get_size() as usize + } +} - // Determine the number of bytes requires to - // represent a Vector4. - vec = Vector4::::zero(); - byte_size = T::get_byte_size(); - num_bytes = byte_size * vec.get_size() as usize; - - // Make sure that there is enough data to read - // the bytes for this type. - assert!(buffer.len() >= num_bytes); - - // Convert the given bytes to this type and return it. - vec.x = T::from_bytes(&buffer[0..byte_size]); - vec.y = T::from_bytes(&buffer[byte_size..(byte_size*2)]); - vec.z = T::from_bytes(&buffer[(byte_size*2)..(byte_size*3)]); - vec.w = T::from_bytes(&buffer[(byte_size*3)..num_bytes]); - vec +#[cfg(feature="convert_sigils")] +impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable +{ + fn from_bytes(buffer: &[u8]) -> Self + { + Self::from_endian_bytes(buffer, Endianess::Platform) } - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Vector4 + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { let byte_size: usize; let num_bytes: usize; @@ -1153,6 +904,46 @@ impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable vec } + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn as_endian_bytes(&self, endianess: Endianess) -> Vec + { + let byte_size: usize; + let num_bytes: usize; + let mut buffer: Vec; + + // Determine the number of bytes requires to + // represent a Vector4. + byte_size = T::get_byte_size(); + num_bytes = byte_size * self.get_size() as usize; + + // Make sure that there is enough space to store + // the bytes from this type. + buffer = Vec::with_capacity(num_bytes); + + // Convert this to bytes and add it to the buffer. + buffer.append(&mut self.x.as_endian_bytes(endianess)); + buffer.append(&mut self.y.as_endian_bytes(endianess)); + buffer.append(&mut self.z.as_endian_bytes(endianess)); + buffer.append(&mut self.w.as_endian_bytes(endianess)); + + // Return the byte buffer. + buffer + } + fn determine_byte_size(&self) -> usize { T::get_byte_size() * self.get_size() as usize @@ -1163,27 +954,48 @@ impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable impl Transmutable for Quaternion where T: Real + ByteSized + Transmutable { - fn as_bytes(&self) -> Vec + fn from_bytes(buffer: &[u8]) -> Self + { + Self::from_endian_bytes(buffer, Endianess::Platform) + } + + fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self { let byte_size: usize; let num_bytes: usize; - let mut buffer: Vec; + let mut quat: Quaternion; // Determine the number of bytes requires to // represent a Quaternion. + quat = Quaternion::::zero(); byte_size = T::get_byte_size(); num_bytes = byte_size * 4usize; - // Make sure that there is enough space to store - // the bytes from this type. - buffer = Vec::with_capacity(num_bytes); + // Make sure that there is enough data to read + // the bytes for this type. + assert!(buffer.len() >= num_bytes); - // Convert this to bytes and add it to the buffer. - buffer.append(&mut self.scalar.as_bytes()); - buffer.append(&mut self.vector.as_bytes()); + // Convert the given bytes to this type and return it. + quat.scalar = T::from_endian_bytes(&buffer[0..byte_size], endianess); + quat.vector = + Vector3::::from_endian_bytes(&buffer[byte_size..num_bytes], + endianess); + quat + } - // Return the byte buffer. - buffer + fn to_bytes(self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) + } + + fn to_endian_bytes(self, endianess: Endianess) -> Vec + { + self.as_endian_bytes(endianess) + } + + fn as_bytes(&self) -> Vec + { + self.as_endian_bytes(Endianess::Platform) } fn as_endian_bytes(&self, endianess: Endianess) -> Vec @@ -1209,53 +1021,6 @@ impl Transmutable for Quaternion buffer } - fn from_bytes(buffer: &[u8]) -> Quaternion - { - let byte_size: usize; - let num_bytes: usize; - let mut quat: Quaternion; - - // Determine the number of bytes requires to - // represent a Quaternion. - quat = Quaternion::::zero(); - byte_size = T::get_byte_size(); - num_bytes = byte_size * 4usize; - - // Make sure that there is enough data to read - // the bytes for this type. - assert!(buffer.len() >= num_bytes); - - // Convert the given bytes to this type and return it. - quat.scalar = T::from_bytes(&buffer[0..byte_size]); - quat.vector = - Vector3::::from_bytes(&buffer[byte_size..num_bytes]); - quat - } - - fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Quaternion - { - let byte_size: usize; - let num_bytes: usize; - let mut quat: Quaternion; - - // Determine the number of bytes requires to - // represent a Quaternion. - quat = Quaternion::::zero(); - byte_size = T::get_byte_size(); - num_bytes = byte_size * 4usize; - - // Make sure that there is enough data to read - // the bytes for this type. - assert!(buffer.len() >= num_bytes); - - // Convert the given bytes to this type and return it. - quat.scalar = T::from_endian_bytes(&buffer[0..byte_size], endianess); - quat.vector = - Vector3::::from_endian_bytes(&buffer[byte_size..num_bytes], - endianess); - quat - } - fn determine_byte_size(&self) -> usize { T::get_byte_size() * 4usize diff --git a/tests/converter.rs b/tests/converter.rs deleted file mode 100644 index 71717ad..0000000 --- a/tests/converter.rs +++ /dev/null @@ -1,249 +0,0 @@ -extern crate rand; - -extern crate alchemy; -extern crate sigils; - - - -use std::thread::{Builder, JoinHandle}; - -use alchemy::{U16_BYTES, U32_BYTES, U64_BYTES}; -use alchemy::{I16_BYTES, I32_BYTES, I64_BYTES}; -use alchemy::{USIZE_BYTES, ISIZE_BYTES}; -use alchemy::{F32_BYTES, F64_BYTES}; - - -const EXHAUSTIVE_RUNS: u64 = 10000u64; - - - -macro_rules! create_thread -{ - ($thread_name: expr, $func_name: ident) => - { - { - let builder: Builder; - - builder = Builder::new().name($thread_name.to_string()); - match builder.spawn($func_name) - { - Ok(handle) => - { - handle - } - - Err(_) => - { - panic!("Error spawning thread: {}.", $thread_name); - } - } - } - } -} - -/// -macro_rules! full_check_impl -{ - ($varType: ident, $read_func: ident, $write_func: ident, $numBytes: expr) => - { - { - use std::$varType; - use rand::ThreadRng; - use rand::distributions::{IndependentSample, Range}; - use alchemy::{Converter, BigEndian, LittleEndian}; - - let range: Range<$varType>; - let mut rng: ThreadRng; - - rng = rand::thread_rng(); - range = Range::new($varType::MIN, $varType::MAX); - for _ in 0..EXHAUSTIVE_RUNS - { - let val: $varType; - let final_big_val: $varType; - let final_little_val: $varType; - let mut buffer: [u8; $numBytes]; - - buffer = [0u8; $numBytes]; - val = range.ind_sample(&mut rng); - - BigEndian::$write_func(&mut buffer, val); - final_big_val = BigEndian::$read_func(&buffer); - if final_big_val != val - { - panic!(false); - } - - LittleEndian::$write_func(&mut buffer, val); - final_little_val = LittleEndian::$read_func(&buffer); - if final_little_val != val - { - panic!(false); - } - } - - true - } - } -} - -/// -macro_rules! full_check -{ - ($func_name: ident, $varType: ident, $read_func: ident, - $write_func: ident) => - { - fn $func_name() -> bool - { - full_check_impl!($varType, $read_func, $write_func, $varType::BYTES) - } - }; - - ($func_name: ident, $varType: ident, - $read_func: ident, $write_func: ident, $numBytes: expr) => - { - fn $func_name() -> bool - { - full_check_impl!($varType, $read_func, $write_func, $numBytes) - } - }; -} - -/// This should only be called by the macro below. -macro_rules! overflow_impl -{ - ($numBytes: expr, $varType: ident, - $read_func: ident, $write_func: ident) => - { - use alchemy::{Converter, BigEndian, LittleEndian}; - use sigils::Zero; - - - #[test] - #[should_panic] - fn read_big_endian() - { - let buffer: [u8; $numBytes - 1]; - - buffer = [0u8; $numBytes - 1]; - BigEndian::$read_func(&buffer); - } - - #[test] - #[should_panic] - fn read_little_endian() - { - let buffer: [u8; $numBytes - 1]; - - buffer = [0u8; $numBytes - 1]; - LittleEndian::$read_func(&buffer); - } - - - #[test] - #[should_panic] - fn write_big_endian() - { - let mut buffer: [u8; $numBytes - 1]; - - buffer = [0u8; $numBytes - 1]; - BigEndian::$write_func(&mut buffer, $varType::zero()); - } - - #[test] - #[should_panic] - fn write_little_endian() - { - let mut buffer: [u8; $numBytes - 1]; - - buffer = [0u8; $numBytes - 1]; - LittleEndian::$write_func(&mut buffer, $varType::zero()); - } - }; -} - -/// This macro tries to test for buffer overflow happening. -macro_rules! test_buffer_overflow -{ - ($mod_name: ident, $varType: ident, - $read_func: ident, $write_func: ident, $numBytes: ident) => - { - mod $mod_name - { - use alchemy::$numBytes; - - overflow_impl!($numBytes, $varType, $read_func, $write_func); - } - } -} - - - -// Test the different data types for buffer overflow. -test_buffer_overflow!(overflow_u16, u16, bytes_to_u16, u16_to_bytes, U16_BYTES); -test_buffer_overflow!(overflow_u32, u32, bytes_to_u32, u32_to_bytes, U32_BYTES); -test_buffer_overflow!(overflow_u64, u64, bytes_to_u64, u64_to_bytes, U64_BYTES); -test_buffer_overflow!(overflow_usize, usize, - bytes_to_usize, usize_to_bytes, U8_BYTES); - -test_buffer_overflow!(overflow_i16, i16, bytes_to_i16, i16_to_bytes, I16_BYTES); -test_buffer_overflow!(overflow_i32, i32, bytes_to_i32, i32_to_bytes, I32_BYTES); -test_buffer_overflow!(overflow_i64, i64, bytes_to_i64, i64_to_bytes, I64_BYTES); -test_buffer_overflow!(overflow_isize, isize, - bytes_to_isize, isize_to_bytes, U8_BYTES); - -test_buffer_overflow!(overflow_f32, f32, bytes_to_f32, f32_to_bytes, F32_BYTES); -test_buffer_overflow!(overflow_f64, f64, bytes_to_f64, f64_to_bytes, F64_BYTES); - -// Create the exhaustive check functions for the integer types. -full_check!(check_u16, u16, bytes_to_u16, u16_to_bytes, U16_BYTES); -full_check!(check_u32, u32, bytes_to_u32, u32_to_bytes, U32_BYTES); -full_check!(check_u64, u64, bytes_to_u64, u64_to_bytes, U64_BYTES); -full_check!(check_usize, usize, bytes_to_usize, usize_to_bytes, USIZE_BYTES); - -full_check!(check_i16, i16, bytes_to_i16, i16_to_bytes, I16_BYTES); -full_check!(check_i32, i32, bytes_to_i32, i32_to_bytes, I32_BYTES); -full_check!(check_i64, i64, bytes_to_i64, i64_to_bytes, I64_BYTES); -full_check!(check_isize, isize, bytes_to_isize, isize_to_bytes, ISIZE_BYTES); - -full_check!(check_f32, f32, bytes_to_f32, f32_to_bytes, F32_BYTES); -full_check!(check_f64, f64, bytes_to_f64, f64_to_bytes, F64_BYTES); - - -#[test] -fn exhaustive_check() -{ - let mut threads: Vec>; - - threads = Vec::new(); - threads.push(create_thread!("u16", check_u16)); - threads.push(create_thread!("u32", check_u32)); - threads.push(create_thread!("u64", check_u64)); - threads.push(create_thread!("usize", check_usize)); - threads.push(create_thread!("i16", check_i16)); - threads.push(create_thread!("i32", check_i32)); - threads.push(create_thread!("i64", check_i64)); - threads.push(create_thread!("isize", check_isize)); - threads.push(create_thread!("f32", check_f32)); - threads.push(create_thread!("f64", check_f64)); - - for handle in threads - { - let mut name: String; - - name = String::new(); - name.push_str(handle.thread().name().unwrap()); - match handle.join() - { - Ok(result) => - { - println!("{}: {}", name, result); - } - - Err(_) => - { - panic!("{}", name); - } - } - } -} diff --git a/tests/transmutable.rs b/tests/transmutable.rs deleted file mode 100644 index 37a1988..0000000 --- a/tests/transmutable.rs +++ /dev/null @@ -1,92 +0,0 @@ -extern crate rand; - -extern crate alchemy; -extern crate sigils; - - - -macro_rules! transmutation_vector_test -{ - ($modName: ident, $varType: ident, $dataType:ty, - $numBytes: expr, [$($var: ident)*]) => - { - mod $modName - { - use rand::{thread_rng, Rng, ThreadRng}; - - use alchemy::{Endianess, Transmutable}; - use sigils::Zero; - use sigils::vector::$varType; - - - - #[test] - pub fn transmutation() - { - let mut vec: $varType<$dataType>; - let final_vec: $varType<$dataType>; - let endianess: Endianess; - let mut rng: ThreadRng; - let mut buffer: [u8; $numBytes]; - - // Initialize the variables. - rng = thread_rng(); - vec = $varType::<$dataType>::zero(); - $(vec.$var = rng.gen();)* - buffer = [0u8; $numBytes]; - endianess = Endianess::PLATFORM; - - vec.to_bytes(&mut buffer, endianess); - final_vec = $varType::from_bytes(&buffer, endianess); - - $(assert_eq!(vec.$var, final_vec.$var);)* - } - } - } -} - - -transmutation_vector_test!(vec2, Vector2, u64, 16, [x y]); -transmutation_vector_test!(vec3, Vector3, u32, 12, [x y z]); -transmutation_vector_test!(vec4, Vector4, u16, 8, [x y z w]); - - - -mod quat -{ - use rand::{thread_rng, Rng, ThreadRng}; - - use alchemy::{Endianess, Transmutable}; - use sigils::Zero; - use sigils::quaternion::Quaternion; - - - - #[test] - pub fn transmutation() - { - let mut quat: Quaternion; - let final_quat: Quaternion; - let endianess: Endianess; - let mut rng: ThreadRng; - let mut buffer: [u8; 32]; - - // Initialize the variables. - rng = thread_rng(); - quat = Quaternion::::zero(); - quat.scalar = rng.gen(); - quat.vector.x = rng.gen(); - quat.vector.y = rng.gen(); - quat.vector.z = rng.gen(); - buffer = [0u8; 32]; - endianess = Endianess::PLATFORM; - - quat.to_bytes(&mut buffer, endianess); - final_quat = Quaternion::from_bytes(&buffer, endianess); - - assert_eq!(quat.scalar, final_quat.scalar); - assert_eq!(quat.vector.x, final_quat.vector.x); - assert_eq!(quat.vector.y, final_quat.vector.y); - assert_eq!(quat.vector.z, final_quat.vector.z); - } -}