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); - } -}