use std::{u8, u16, u32, u64, usize}; use std::{i8, i16, i32, i64, isize}; use ::converter::Converter; use ::endian::{BigEndian, LittleEndian, PlatformEndian, Endianess}; /// Handles the repetative macro_rules! handle_endianess_to_bytes { ($buffer: ident, $val: ident, $endianess: ident, $func: ident) => { { let mut mut_buffer; mut_buffer = $buffer; match $endianess { Endianess::BIG => { BigEndian::$func(&mut mut_buffer, *$val); } Endianess::LITTLE => { LittleEndian::$func(&mut mut_buffer, *$val); } Endianess::PLATFORM => { PlatformEndian::$func(&mut mut_buffer, *$val); } } } } } 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) } } } } // 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 to_bytes(&self, buffer: &mut [u8], endianess: Endianess); /// Transmute an array of bytes to this type. fn from_bytes(buffer: &[u8], endianess: Endianess) -> Self; } impl Transmutable for u8 { #[allow(unused_variables)] fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= u8::BYTES); // Convert this to bytes and add it to the buffer. // Endianess doesn't matter here. buffer[0] = *self; } #[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] } } impl Transmutable for u16 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= u16::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, u16_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u16) } } impl Transmutable for u32 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= u32::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, u32_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u32) } } impl Transmutable for u64 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= u64::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, u64_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u64) } } impl Transmutable for usize { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= usize::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, usize_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_usize) } } impl Transmutable for i8 { #[allow(unused_variables)] fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= i8::BYTES); // Convert this to bytes and add it to the buffer. buffer[0] = *self as u8; } #[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 } } impl Transmutable for i16 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= i16::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, i16_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i16) } } impl Transmutable for i32 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= i32::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, i32_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i32) } } impl Transmutable for i64 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= i64::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, i64_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i64) } } impl Transmutable for isize { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= isize::BYTES); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, isize_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_isize) } } impl Transmutable for f32 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= 4); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, f32_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_f32) } } impl Transmutable for f64 { fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) { // Make sure that there is enough space to store // the bytes from this type. assert!(buffer.len() >= 8); // Convert this to bytes and add it to the buffer. handle_endianess_to_bytes!(buffer, self, endianess, f64_to_bytes); } 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 is. handle_endianess_from_bytes!(buffer, endianess, bytes_to_f64) } }