use sigils::{Zero, Number, Real}; use sigils::vector::{Vector, Vector2, Vector3, Vector4}; use sigils::quaternion::Quaternion; use ::byte_sized::{ByteSized, get_byte_size_of_string}; use ::converter::Converter; use ::endian::{BigEndian, LittleEndian, PlatformEndian, NetworkEndian}; use ::endian::Endianess; // From and Into are not used because we need to also // know the endianess to use for converting. /// A type that can be converted to and from bytes. pub trait Transmutable { /// Transmute an array of bytes to this type. fn from_bytes(buffer: &[u8], endianess: Endianess) -> Self; /// Transmute this type to an array of bytes. fn to_bytes(&self, endianess: Endianess) -> Vec; /// Get the current size of this Transmutable in bytes. fn determine_byte_size(&self) -> usize; } /// Handles the repetative endianess matching /// for the primitive number types when converting /// a number to bytes. macro_rules! handle_endianess_to_bytes { ($buffer: ident, $val: ident, $endianess: ident, $func: ident) => { { match $endianess { Endianess::Big => { $buffer.append(&mut BigEndian::$func(*$val)); } Endianess::Little => { $buffer.append(&mut LittleEndian::$func(*$val)); } Endianess::Platform => { $buffer.append(&mut PlatformEndian::$func(*$val)); } Endianess::Network => { $buffer.append(&mut NetworkEndian::$func(*$val)); } } } } } /// Handles the repetative endianess matching /// for the primitive number types when converting /// a number from bytes. macro_rules! handle_endianess_from_bytes { ($buffer: ident, $endianess: ident, $func: ident) => { match $endianess { Endianess::Big => { BigEndian::$func(&$buffer) } Endianess::Little => { LittleEndian::$func(&$buffer) } Endianess::Platform => { PlatformEndian::$func(&$buffer) } Endianess::Network => { NetworkEndian::$func(&$buffer) } } } } impl Transmutable for u8 { #[allow(unused_variables)] fn from_bytes(buffer: &[u8], endianess: Endianess) -> u8 { // 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. buffer[0] } #[allow(unused_variables)] fn to_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 determine_byte_size(&self) -> usize { u8::BYTES } } impl Transmutable for u16 { fn from_bytes(buffer: &[u8], endianess: Endianess) -> u16 { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= u16::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u16) } fn to_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 determine_byte_size(&self) -> usize { u16::BYTES } } impl Transmutable for u32 { fn from_bytes(buffer: &[u8], endianess: Endianess) -> u32 { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= u32::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u32) } fn to_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 determine_byte_size(&self) -> usize { u32::BYTES } } impl Transmutable for u64 { fn from_bytes(buffer: &[u8], endianess: Endianess) -> u64 { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= u64::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u64) } fn to_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 determine_byte_size(&self) -> usize { u64::BYTES } } impl Transmutable for usize { fn from_bytes(buffer: &[u8], endianess: Endianess) -> usize { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= usize::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_usize) } fn to_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 determine_byte_size(&self) -> usize { usize::BYTES } } impl Transmutable for i8 { #[allow(unused_variables)] fn from_bytes(buffer: &[u8], endianess: Endianess) -> i8 { // 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 } #[allow(unused_variables)] fn to_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 determine_byte_size(&self) -> usize { i8::BYTES } } impl Transmutable for i16 { fn from_bytes(buffer: &[u8], endianess: Endianess) -> i16 { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= i16::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i16) } fn to_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 determine_byte_size(&self) -> usize { i16::BYTES } } impl Transmutable for i32 { fn from_bytes(buffer: &[u8], endianess: Endianess) -> i32 { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= i32::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i32) } fn to_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 determine_byte_size(&self) -> usize { i32::BYTES } } impl Transmutable for i64 { fn from_bytes(buffer: &[u8], endianess: Endianess) -> i64 { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= i64::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i64) } fn to_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 determine_byte_size(&self) -> usize { i64::BYTES } } impl Transmutable for isize { fn from_bytes(buffer: &[u8], endianess: Endianess) -> isize { // Make sure that there is enough data to read // the bytes for this type. assert!(buffer.len() >= isize::BYTES); // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_isize) } fn to_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 determine_byte_size(&self) -> usize { isize::BYTES } } impl Transmutable for f32 { fn from_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) } fn to_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 determine_byte_size(&self) -> usize { f32::BYTES } } impl Transmutable for f64 { fn from_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) } fn to_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 determine_byte_size(&self) -> usize { f64::BYTES } } impl Transmutable for String { fn from_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 to_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)); } Endianess::Little => { buffer.append(&mut LittleEndian::string_to_bytes(temp)); } Endianess::Platform => { buffer.append(&mut PlatformEndian::string_to_bytes(temp)); } Endianess::Network => { buffer.append(&mut NetworkEndian::string_to_bytes(temp)); } } // Return the byte buffer. buffer } fn determine_byte_size(&self) -> usize { get_byte_size_of_string(self) } } impl Transmutable for Vector2 where T: Number + ByteSized + Transmutable { fn from_bytes(buffer: &[u8], endianess: Endianess) -> 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], endianess); vec.y = T::from_bytes(&buffer[byte_size..num_bytes], endianess); vec } fn to_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.to_bytes(endianess)); buffer.append(&mut self.y.to_bytes(endianess)); // Return the byte buffer. buffer } fn determine_byte_size(&self) -> usize { T::get_byte_size() * self.get_size() as usize } } impl Transmutable for Vector3 where T: Number + ByteSized + Transmutable { 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 } fn to_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.to_bytes(endianess)); buffer.append(&mut self.y.to_bytes(endianess)); buffer.append(&mut self.z.to_bytes(endianess)); // Return the byte buffer. buffer } fn determine_byte_size(&self) -> usize { T::get_byte_size() * self.get_size() as usize } } impl Transmutable for Vector4 where T: Number + ByteSized + Transmutable { 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 } fn to_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.to_bytes(endianess)); buffer.append(&mut self.y.to_bytes(endianess)); buffer.append(&mut self.z.to_bytes(endianess)); buffer.append(&mut self.w.to_bytes(endianess)); // Return the byte buffer. buffer } fn determine_byte_size(&self) -> usize { T::get_byte_size() * self.get_size() as usize } } impl Transmutable for Quaternion where T: Real + ByteSized + Transmutable { fn from_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_bytes(&buffer[0..byte_size], endianess); quat.vector = Vector3::::from_bytes(&buffer[byte_size..num_bytes], endianess); quat } fn to_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 Quaternion. 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); // Convert this to bytes and add it to the buffer. buffer.append(&mut self.scalar.to_bytes(endianess)); buffer.append(&mut self.vector.to_bytes(endianess)); // Return the byte buffer. buffer } fn determine_byte_size(&self) -> usize { T::get_byte_size() * 4usize } }