use std::mem; /// Describes types that can transmute Numbers into bytes, /// or bytes into Numbers. This means that they can also /// transmute higher order mathematic types like Vectors, /// Quaternions, Matrices, and such. pub trait Transmutable { /// Converts an array of bytes to a signed 16-bit integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_i16(buffer: &[u8]) -> i16 { Self::bytes_to_u16(buffer) as i16 } /// Converts an array of bytes to a signed 32-bit integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_i32(buffer: &[u8]) -> i32 { Self::bytes_to_u32(buffer) as i32 } /// Converts an array of bytes to a signed 64-bit integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_i64(buffer: &[u8]) -> i64 { Self::bytes_to_u64(buffer) as i64 } /// Converts an array of bytes to a signed integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. /// /// This will panic if the number of bytes /// passed in is less than one or more than eight. fn bytes_to_isize(buffer: &[u8]) -> isize { let temp_num: u64; assert!(buffer.len() >= 1 && buffer.len() <= 8); temp_num = Self::bytes_to_usize(buffer) as u64; add_sign(temp_num, buffer.len() as u8) as isize } /// Converts an array of bytes to a 32-bit floating point number. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_f32(buffer: &[u8]) -> f32 { unsafe { mem::transmute::(Self::bytes_to_u32(buffer)) } } /// Converts an array of bytes to a 64-bit floating point number. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_f64(buffer: &[u8]) -> f64 { unsafe { mem::transmute::(Self::bytes_to_u64(buffer)) } } /// Converts a signed 16-bit integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn i16_to_bytes(buffer: &mut [u8], num: i16) { Self::u16_to_bytes(buffer, num as u16) } /// Converts a signed 32-bit integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn i32_to_bytes(buffer: &mut [u8], num: i32) { Self::u32_to_bytes(buffer, num as u32) } /// Converts a signed 64-bit integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn i64_to_bytes(buffer: &mut [u8], num: i64) { Self::u64_to_bytes(buffer, num as u64) } /// Converts a signed integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. /// /// This will panic if the number of bytes /// passed in is less than the byte size of the given number /// or more than eight. fn isize_to_bytes(buffer: &mut [u8], num: isize) { let temp_num: usize; assert!(buffer.len() >= 1 && buffer.len() <= 8); temp_num = remove_sign(num as i64, buffer.len() as u8) as usize; Self::usize_to_bytes(buffer, temp_num) } /// Converts a 32-bit floating point number to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn f32_to_bytes(buffer: &mut [u8], num: f32) { unsafe { Self::u32_to_bytes(buffer, mem::transmute::(num)); } } /// Converts a 64-bit floating point number to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn f64_to_bytes(buffer: &mut [u8], num: f64) { unsafe { Self::u64_to_bytes(buffer, mem::transmute::(num)); } } /// Converts an array of bytes to an unsigned 16-bit integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_u16(buffer: &[u8]) -> u16; /// Converts an array of bytes to an unsigned 32-bit integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_u32(buffer: &[u8]) -> u32; /// Converts an array of bytes to an unsigned 64-bit integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. fn bytes_to_u64(buffer: &[u8]) -> u64; /// Converts an array of bytes to an unsigned integer. /// /// # Panics /// This will panic if the buffer does not have /// enough information to convert. /// /// This will panic if the number of bytes /// passed in is less than one or more than eight. fn bytes_to_usize(buffer: &[u8]) -> usize; /// Converts an unsigned 16-bit integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn u16_to_bytes(buffer: &mut [u8], num: u16); /// Converts an unsigned 32-bit integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn u32_to_bytes(buffer: &mut [u8], num: u32); /// Converts an unsigned 64-bit integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. fn u64_to_bytes(buffer: &mut [u8], num: u64); /// Converts an unsigned integer to bytes /// and places them into the given buffer. /// /// # Panics /// This will panic if the buffer does not have /// enough space to store the converted value. /// /// This will panic if the number of bytes /// passed in is less than the byte size of the given number /// or more than eight. fn usize_to_bytes(buffer: &mut [u8], num: usize); } /// Switches an unsigned value into its signed equivalent. /// /// NOTE: This seems messy for larger unsigned values. fn add_sign(val: u64, num_bytes: u8) -> i64 { let shift: u8; shift = (8 - num_bytes) * 8; (val << shift) as i64 >> shift } /// Switches a signed value into its unsigned equivalent. /// /// NOTE: This seems messy for values under zero. fn remove_sign(val: i64, num_bytes: u8) -> u64 { let shift: u8; shift = (8 - num_bytes) * 8; (val << shift) as u64 >> shift } pub enum Endianess { BIG, LITTLE, PLATFORM } pub trait fff { fn to_bytes(&self, buffer: &mut [u8]); fn from_bytes(buffer: &[u8]) -> Self; }