alchemy/src/transmutable.rs

276 lines
7.3 KiB
Rust
Raw Normal View History

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::<u32, f32>(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::<u64, f64>(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::<f32, u32>(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::<f64, u64>(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;
}