alchemy/src/transmutable.rs

1264 lines
33 KiB
Rust
Raw Normal View History

#[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;
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 this type to an array of bytes.
fn as_bytes(&self) -> Vec<u8>;
/// Transmute this type to an array of bytes.
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>;
/// Transmute an array of bytes to this type.
fn from_bytes(buffer: &[u8]) -> Self;
/// Transmute an array of bytes to this type.
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self;
/// 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)
}
}
}
}
/// 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<u8>;
// 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<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, u8::BYTES)
}
#[allow(unused_variables)]
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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]
}
fn determine_byte_size(&self) -> usize
{
u8::BYTES
}
}
impl Transmutable for u16
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, u16::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
u16::BYTES
}
}
impl Transmutable for u32
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, u32::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
u32::BYTES
}
}
impl Transmutable for u64
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, u64::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
u64::BYTES
}
}
impl Transmutable for usize
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, usize::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
usize::BYTES
}
}
impl Transmutable for i8
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, i8::BYTES)
}
#[allow(unused_variables)]
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
i8::BYTES
}
}
impl Transmutable for i16
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, i16::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
i16::BYTES
}
}
impl Transmutable for i32
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, i32::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
i32::BYTES
}
}
impl Transmutable for i64
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, i64::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
i64::BYTES
}
}
impl Transmutable for isize
{
fn as_bytes(&self) -> Vec<u8>
{
// Unpack the bits that make up this value and
// return a buffer of the bytes.
unpack_bits!(*self, isize::BYTES)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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
{
// 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 determine_byte_size(&self) -> usize
{
isize::BYTES
}
}
impl Transmutable for f32
{
fn as_bytes(&self) -> Vec<u8>
{
let value: u32;
unsafe
{
value = ::std::mem::transmute::<f32, u32>(*self);
}
value.as_bytes()
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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, f32>(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)
}
fn determine_byte_size(&self) -> usize
{
f32::BYTES
}
}
impl Transmutable for f64
{
fn as_bytes(&self) -> Vec<u8>
{
let value: u64;
unsafe
{
value = ::std::mem::transmute::<f64, u64>(*self);
}
value.as_bytes()
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let mut buffer: Vec<u8>;
// 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, f64>(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)
}
fn determine_byte_size(&self) -> usize
{
f64::BYTES
}
}
impl Transmutable for String
{
fn as_bytes(&self) -> Vec<u8>
{
let bytes: &[u8];
let byte_count: u64;
let mut buffer: Vec<u8>;
// 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
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let temp: String;
let mut buffer: Vec<u8>;
// 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 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
{
get_byte_size_of_string(self)
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable
{
fn as_bytes(&self) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector2<T>;
// Determine the number of bytes requires to
// represent a Vector2.
vec = Vector2::<T>::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<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector2<T>;
// Determine the number of bytes requires to
// represent a Vector2.
vec = Vector2::<T>::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_endian_bytes(&buffer[0..byte_size],
endianess);
vec.y = T::from_endian_bytes(&buffer[byte_size..num_bytes],
endianess);
vec
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Vector3<T> where T: Number + ByteSized + Transmutable
{
fn as_bytes(&self) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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());
buffer.append(&mut self.z.as_bytes());
// Return the byte buffer.
buffer
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector3<T>;
// Determine the number of bytes requires to
// represent a Vector3.
vec = Vector3::<T>::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
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Vector3<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector3<T>;
// Determine the number of bytes requires to
// represent a Vector3.
vec = Vector3::<T>::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_endian_bytes(&buffer[0..byte_size],
endianess);
vec.y = T::from_endian_bytes(&buffer[byte_size..(byte_size*2)],
endianess);
vec.z = T::from_endian_bytes(&buffer[(byte_size*2)..num_bytes],
endianess);
vec
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Vector4<T> where T: Number + ByteSized + Transmutable
{
fn as_bytes(&self) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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 from_bytes(buffer: &[u8]) -> Vector4<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector4<T>;
// Determine the number of bytes requires to
// represent a Vector4.
vec = Vector4::<T>::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
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Vector4<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector4<T>;
// Determine the number of bytes requires to
// represent a Vector4.
vec = Vector4::<T>::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_endian_bytes(&buffer[0..byte_size],
endianess);
vec.y = T::from_endian_bytes(&buffer[byte_size..(byte_size*2)],
endianess);
vec.z = T::from_endian_bytes(&buffer[(byte_size*2)..(byte_size*3)],
endianess);
vec.w = T::from_endian_bytes(&buffer[(byte_size*3)..num_bytes],
endianess);
vec
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Quaternion<T>
where T: Real + ByteSized + Transmutable
{
fn as_bytes(&self) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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.as_bytes());
buffer.append(&mut self.vector.as_bytes());
// Return the byte buffer.
buffer
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// 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.as_endian_bytes(endianess));
buffer.append(&mut self.vector.as_endian_bytes(endianess));
// Return the byte buffer.
buffer
}
fn from_bytes(buffer: &[u8]) -> Quaternion<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut quat: Quaternion<T>;
// Determine the number of bytes requires to
// represent a Quaternion.
quat = Quaternion::<T>::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::<T>::from_bytes(&buffer[byte_size..num_bytes]);
quat
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Quaternion<T>
{
let byte_size: usize;
let num_bytes: usize;
let mut quat: Quaternion<T>;
// Determine the number of bytes requires to
// represent a Quaternion.
quat = Quaternion::<T>::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::<T>::from_endian_bytes(&buffer[byte_size..num_bytes],
endianess);
quat
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * 4usize
}
}