diff --git a/examples/convert_f32.rs b/examples/convert_f32.rs index 4ba1759..e698501 100644 --- a/examples/convert_f32.rs +++ b/examples/convert_f32.rs @@ -4,11 +4,11 @@ extern crate alchemy; use alchemy::F32_BYTES; -use alchemy::{Converter, PlatformEndian}; +use alchemy::{Converter, Endianess, PlatformEndian, Transmutable}; -pub fn main() +fn use_converter() { let num: f32; let final_num: f32; @@ -31,6 +31,31 @@ pub fn main() println!("The buffer converts back to: {}", final_num); } +pub fn use_transmutable() +{ + let num: f32; + let final_num: f32; + let endianess: Endianess; + let mut buffer: [u8; F32_BYTES]; + + // Initialize the variables. + num = 6.291985f32; + buffer = [0u8; F32_BYTES]; + endianess = Endianess::PLATFORM; + + println!("Converting the value {} into and out of an array of bytes.", num); + println!("Buffer starts as: {}", stringify_array(&buffer)); + + // Convert the floating point number into an array of bytes. + num.to_bytes(&mut buffer, endianess); + + println!("Buffer contains: {}", stringify_array(&buffer)); + + // Convert the array of bytes into a floating point number. + final_num = f32::from_bytes(&buffer, endianess); + println!("The buffer converts back to: {}", final_num); +} + /// This just help pretty up the printing of an array of bytes. fn stringify_array(buffer: &[u8]) -> String { @@ -68,3 +93,16 @@ fn stringify_array(buffer: &[u8]) -> String result.push_str("]"); result } + + +pub fn main() +{ + println!("Using converter:"); + use_converter(); + + println!(""); + + println!("Using transmutable:"); + use_transmutable(); +} + diff --git a/examples/convert_vector2.rs b/examples/convert_vector2.rs new file mode 100644 index 0000000..1679afb --- /dev/null +++ b/examples/convert_vector2.rs @@ -0,0 +1,86 @@ +#![feature(convert)] + +extern crate alchemy; +extern crate sigils; + + + +use alchemy::U64_BYTES; +use alchemy::{Endianess, Transmutable}; +use sigils::vector::Vector2; + + + +/// The size of 2 u64 whole numbers. +/// This would be different if the contained type +/// was something different, like an i16 or f32. +const SIZE_OF_VECTOR_2: usize = U64_BYTES * 2; + + + +/// This just help pretty up the printing of an array of bytes. +fn stringify_array(buffer: &[u8]) -> String +{ + let mut result: String; + let mut count: usize; + + // Create a new string that starts with just + // the array opening bracket. + result = String::new(); + result.push_str("["); + + // Loop through the buffer keeping track + // of our place in it. + count = 0usize; + for byte in buffer + { + // Handle priting the last value differently. + if count >= buffer.len() - 1 + { + result.push_str(byte.to_string().as_str()); + } + else + { + result.push_str(byte.to_string().as_str()); + result.push_str(", "); + } + + // Mark that we are going to look at + // the next byte in the array. + count += 1; + } + + // Add the array closing bracket and + // return the new String. + result.push_str("]"); + result +} + + +pub fn main() +{ + let vec: Vector2; + let final_vec: Vector2; + let endianess: Endianess; + let mut buffer: [u8; SIZE_OF_VECTOR_2]; + + // Initialize the variables. + vec = Vector2::::new(629u64, 1985u64); + buffer = [0u8; SIZE_OF_VECTOR_2]; + endianess = Endianess::PLATFORM; + + println!("Transmuting a Vector2:"); + + println!("Converting the value [{}, {}] into and out of an array of bytes.", + vec.x, vec.y); + println!("Buffer starts as: {}", stringify_array(&buffer)); + + // Convert the Vector2 into an array of bytes. + vec.to_bytes(&mut buffer, endianess); + + println!("Buffer contains: {}", stringify_array(&buffer)); + + // Convert the array of bytes into a Vector2. + final_vec = Vector2::from_bytes(&buffer, endianess); + println!("The buffer converts back to: [{}, {}]", final_vec.x, final_vec.y); +} diff --git a/src/transmutable.rs b/src/transmutable.rs index 4ab6b80..dbba8d7 100644 --- a/src/transmutable.rs +++ b/src/transmutable.rs @@ -1,5 +1,5 @@ use sigils::{Zero, Number}; -use sigils::vector::{Vector, Vector2}; +use sigils::vector::{Vector, Vector2, Vector3, Vector4}; use ::byte_sized::ByteSized; use ::converter::Converter; @@ -408,3 +408,97 @@ impl Transmutable for Vector2 where T: Number + ByteSized + Transmutable vec } } + +impl Transmutable for Vector3 where T: Number + ByteSized + Transmutable +{ + fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) + { + let byte_size: usize; + let num_bytes: usize; + + // 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. + assert!(buffer.len() >= num_bytes); + + // Convert this to bytes and add it to the buffer. + self.x.to_bytes(&mut buffer[0..byte_size], endianess); + self.y.to_bytes(&mut buffer[byte_size..(byte_size*2)], endianess); + self.z.to_bytes(&mut buffer[(byte_size*2)..num_bytes], endianess); + } + + fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector3 + { + let byte_size: usize; + let num_bytes: usize; + let mut vec: Vector3; + + // 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], endianess); + vec.y = T::from_bytes(&buffer[byte_size..(byte_size*2)], endianess); + vec.z = T::from_bytes(&buffer[(byte_size*2)..num_bytes], endianess); + vec + } +} + +impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable +{ + fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) + { + let byte_size: usize; + let num_bytes: usize; + + // 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. + assert!(buffer.len() >= num_bytes); + + // Convert this to bytes and add it to the buffer. + self.x.to_bytes(&mut buffer[0..byte_size], endianess); + self.y.to_bytes(&mut buffer[byte_size..(byte_size*2)], endianess); + self.z.to_bytes(&mut buffer[(byte_size*2)..(byte_size*3)], endianess); + self.w.to_bytes(&mut buffer[(byte_size*3)..num_bytes], endianess); + } + + fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector4 + { + let byte_size: usize; + let num_bytes: usize; + let mut vec: Vector4; + + // 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], endianess); + vec.y = T::from_bytes(&buffer[byte_size..(byte_size*2)], endianess); + vec.z = T::from_bytes(&buffer[(byte_size*2)..(byte_size*3)], endianess); + vec.w = T::from_bytes(&buffer[(byte_size*3)..num_bytes], endianess); + vec + } +} diff --git a/tests/lib.rs b/tests/converter.rs similarity index 98% rename from tests/lib.rs rename to tests/converter.rs index 311c62c..8c7f87c 100644 --- a/tests/lib.rs +++ b/tests/converter.rs @@ -1,5 +1,3 @@ -#![feature(zero_one)] - extern crate rand; extern crate alchemy; @@ -49,6 +47,7 @@ macro_rules! full_check_impl ($T: ident, $read_func: ident, $write_func: ident, $numBytes: expr) => { { + use std::$T; use rand::ThreadRng; use rand::distributions::{IndependentSample, Range}; use alchemy::{Converter, BigEndian, LittleEndian}; @@ -57,7 +56,7 @@ macro_rules! full_check_impl let mut rng: ThreadRng; rng = rand::thread_rng(); - range = Range::new(std::$T::MIN, std::$T::MAX); + range = Range::new($T::MIN, $T::MAX); for _ in 0..EXHAUSTIVE_RUNS { let val: $T; @@ -116,7 +115,7 @@ macro_rules! overflow_impl $read_func: ident, $write_func: ident) => { use alchemy::{Converter, BigEndian, LittleEndian}; - + use sigils::Zero; #[test] @@ -171,7 +170,6 @@ macro_rules! test_buffer_overflow mod $mod_name { use alchemy::$numBytes; - use std::num::Zero; overflow_impl!($numBytes, $T, $read_func, $write_func); } diff --git a/tests/transmutable.rs b/tests/transmutable.rs new file mode 100644 index 0000000..a6a8c1a --- /dev/null +++ b/tests/transmutable.rs @@ -0,0 +1,50 @@ +extern crate rand; + +extern crate alchemy; +extern crate sigils; + + + +macro_rules! transmutation_test +{ + ($modName: ident, $varType: ident, $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; + let final_vec: $varType; + let endianess: Endianess; + let mut rng: ThreadRng; + let mut buffer: [u8; $numBytes]; + + // Initialize the variables. + rng = thread_rng(); + vec = $varType::::zero(); + $(vec.$var = rng.next_u64();)* + 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_test!(vec2, Vector2, 16, [x y]); +transmutation_test!(vec3, Vector3, 24, [x y z]); +transmutation_test!(vec4, Vector4, 32, [x y z w]);