Added a function to determine a Transmutables current byte size.

This was added so that when parsing groups of Transmutables it is easy
to determine your position in the byte array.
This commit is contained in:
Jason Travis Smith 2016-04-14 18:08:50 -04:00
parent 6ff27de3c7
commit 26080427c0

View File

@ -13,11 +13,14 @@ use ::endian::{BigEndian, LittleEndian, PlatformEndian, Endianess};
/// A type that can be converted to and from bytes. /// A type that can be converted to and from bytes.
pub trait Transmutable 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. /// Transmute this type to an array of bytes.
fn to_bytes(&self, endianess: Endianess) -> Vec<u8>; fn to_bytes(&self, endianess: Endianess) -> Vec<u8>;
/// Transmute an array of bytes to this type. /// Get the current size of this Transmutable in bytes.
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Self; fn determine_byte_size(&self) -> usize;
} }
@ -82,6 +85,18 @@ macro_rules! handle_endianess_from_bytes
impl Transmutable for u8 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)] #[allow(unused_variables)]
fn to_bytes(&self, endianess: Endianess) -> Vec<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
@ -98,21 +113,24 @@ impl Transmutable for u8
buffer buffer
} }
#[allow(unused_variables)] fn determine_byte_size(&self) -> usize
fn from_bytes(buffer: &[u8], endianess: Endianess) -> u8
{ {
// Make sure that there is enough data to read u8::BYTES
// 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]
} }
} }
impl Transmutable for u16 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -128,19 +146,24 @@ impl Transmutable for u16
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> u16 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read u16::BYTES
// 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)
} }
} }
impl Transmutable for u32 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -156,19 +179,24 @@ impl Transmutable for u32
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> u32 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read u32::BYTES
// 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)
} }
} }
impl Transmutable for u64 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -184,19 +212,24 @@ impl Transmutable for u64
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> u64 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read u64::BYTES
// 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)
} }
} }
impl Transmutable for usize 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -212,19 +245,26 @@ impl Transmutable for usize
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> usize fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read usize::BYTES
// 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)
} }
} }
impl Transmutable for i8 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)] #[allow(unused_variables)]
fn to_bytes(&self, endianess: Endianess) -> Vec<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
@ -241,21 +281,24 @@ impl Transmutable for i8
buffer buffer
} }
#[allow(unused_variables)] fn determine_byte_size(&self) -> usize
fn from_bytes(buffer: &[u8], endianess: Endianess) -> i8
{ {
// Make sure that there is enough data to read i8::BYTES
// 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
} }
} }
impl Transmutable for i16 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -271,19 +314,24 @@ impl Transmutable for i16
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> i16 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read i16::BYTES
// 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)
} }
} }
impl Transmutable for i32 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -299,19 +347,24 @@ impl Transmutable for i32
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> i32 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read i32::BYTES
// 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)
} }
} }
impl Transmutable for i64 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -327,19 +380,24 @@ impl Transmutable for i64
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> i64 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read i64::BYTES
// 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)
} }
} }
impl Transmutable for isize 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -355,19 +413,24 @@ impl Transmutable for isize
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> isize fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read isize::BYTES
// 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)
} }
} }
impl Transmutable for f32 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -383,19 +446,24 @@ impl Transmutable for f32
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> f32 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read f32::BYTES
// 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)
} }
} }
impl Transmutable for f64 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let mut buffer: Vec<u8>; let mut buffer: Vec<u8>;
@ -411,19 +479,20 @@ impl Transmutable for f64
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> f64 fn determine_byte_size(&self) -> usize
{ {
// Make sure that there is enough data to read f64::BYTES
// 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)
} }
} }
impl Transmutable for String 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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let temp: String; let temp: String;
@ -461,15 +530,36 @@ impl Transmutable for String
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> String fn determine_byte_size(&self) -> usize
{ {
// Convert the given bytes to this type and return it. get_byte_size_of_string(self)
handle_endianess_from_bytes!(buffer, endianess, bytes_to_string)
} }
} }
impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable
{ {
fn from_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_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<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let byte_size: usize; let byte_size: usize;
@ -493,15 +583,23 @@ impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector2<T> fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
impl<T> Transmutable for Vector3<T> where T: Number + ByteSized + Transmutable
{
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector3<T>
{ {
let byte_size: usize; let byte_size: usize;
let num_bytes: usize; let num_bytes: usize;
let mut vec: Vector2<T>; let mut vec: Vector3<T>;
// Determine the number of bytes requires to // Determine the number of bytes requires to
// represent a Vector2. // represent a Vector3.
vec = Vector2::<T>::zero(); vec = Vector3::<T>::zero();
byte_size = T::get_byte_size(); byte_size = T::get_byte_size();
num_bytes = byte_size * vec.get_size() as usize; num_bytes = byte_size * vec.get_size() as usize;
@ -511,13 +609,11 @@ impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable
// Convert the given bytes to this type and return it. // Convert the given bytes to this type and return it.
vec.x = T::from_bytes(&buffer[0..byte_size], endianess); vec.x = T::from_bytes(&buffer[0..byte_size], endianess);
vec.y = T::from_bytes(&buffer[byte_size..num_bytes], 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 vec
} }
}
impl<T> Transmutable for Vector3<T> where T: Number + ByteSized + Transmutable
{
fn to_bytes(&self, endianess: Endianess) -> Vec<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let byte_size: usize; let byte_size: usize;
@ -542,15 +638,23 @@ impl<T> Transmutable for Vector3<T> where T: Number + ByteSized + Transmutable
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector3<T> fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
impl<T> Transmutable for Vector4<T> where T: Number + ByteSized + Transmutable
{
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector4<T>
{ {
let byte_size: usize; let byte_size: usize;
let num_bytes: usize; let num_bytes: usize;
let mut vec: Vector3<T>; let mut vec: Vector4<T>;
// Determine the number of bytes requires to // Determine the number of bytes requires to
// represent a Vector3. // represent a Vector4.
vec = Vector3::<T>::zero(); vec = Vector4::<T>::zero();
byte_size = T::get_byte_size(); byte_size = T::get_byte_size();
num_bytes = byte_size * vec.get_size() as usize; num_bytes = byte_size * vec.get_size() as usize;
@ -561,13 +665,11 @@ impl<T> Transmutable for Vector3<T> where T: Number + ByteSized + Transmutable
// Convert the given bytes to this type and return it. // Convert the given bytes to this type and return it.
vec.x = T::from_bytes(&buffer[0..byte_size], endianess); vec.x = T::from_bytes(&buffer[0..byte_size], endianess);
vec.y = T::from_bytes(&buffer[byte_size..(byte_size*2)], 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.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 vec
} }
}
impl<T> Transmutable for Vector4<T> where T: Number + ByteSized + Transmutable
{
fn to_bytes(&self, endianess: Endianess) -> Vec<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let byte_size: usize; let byte_size: usize;
@ -593,34 +695,38 @@ impl<T> Transmutable for Vector4<T> where T: Number + ByteSized + Transmutable
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector4<T> fn determine_byte_size(&self) -> usize
{ {
let byte_size: usize; T::get_byte_size() * self.get_size() as 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], 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
} }
} }
impl<T> Transmutable for Quaternion<T> impl<T> Transmutable for Quaternion<T>
where T: Real + ByteSized + Transmutable where T: Real + ByteSized + Transmutable
{ {
fn from_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_bytes(&buffer[0..byte_size], endianess);
quat.vector =
Vector3::<T>::from_bytes(&buffer[byte_size..num_bytes], endianess);
quat
}
fn to_bytes(&self, endianess: Endianess) -> Vec<u8> fn to_bytes(&self, endianess: Endianess) -> Vec<u8>
{ {
let byte_size: usize; let byte_size: usize;
@ -644,26 +750,8 @@ impl<T> Transmutable for Quaternion<T>
buffer buffer
} }
fn from_bytes(buffer: &[u8], endianess: Endianess) -> Quaternion<T> fn determine_byte_size(&self) -> usize
{ {
let byte_size: usize; T::get_byte_size() * 4usize
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], endianess);
quat.vector =
Vector3::<T>::from_bytes(&buffer[byte_size..num_bytes], endianess);
quat
} }
} }