diff --git a/Cargo.lock b/Cargo.lock index cd4cbf0..f56dd6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,7 +33,7 @@ dependencies = [ [[package]] name = "sigils" version = "0.1.0" -source = "git+https://gitlab.com/CyberMages/sigils.git#a618fb27f7ceaaa3f75b334dd8ec716ff795273a" +source = "git+https://gitlab.com/CyberMages/sigils.git#9306a73f9a0d03a15f0f870fee18024880c7cf2a" [[package]] name = "winapi" diff --git a/examples/convert_f32.rs b/examples/convert_f32.rs index 86c826f..4ba1759 100644 --- a/examples/convert_f32.rs +++ b/examples/convert_f32.rs @@ -3,6 +3,7 @@ extern crate alchemy; +use alchemy::F32_BYTES; use alchemy::{Converter, PlatformEndian}; @@ -11,11 +12,11 @@ pub fn main() { let num: f32; let final_num: f32; - let mut buffer: [u8; 4]; + let mut buffer: [u8; F32_BYTES]; // Initialize the variables. num = 6.291985f32; - buffer = [0u8; 4]; + buffer = [0u8; F32_BYTES]; println!("Converting the value {} into and out of an array of bytes.", num); println!("Buffer starts as: {}", stringify_array(&buffer)); diff --git a/src/endian.rs b/src/endian.rs index 7d878de..616f562 100644 --- a/src/endian.rs +++ b/src/endian.rs @@ -1,6 +1,8 @@ use std::mem; use std::ptr::copy_nonoverlapping; +use ::byte_sized::ByteSized; +use ::byte_sized::{U16_BYTES, U32_BYTES, U64_BYTES}; use ::converter::Converter; @@ -30,6 +32,7 @@ pub type PlatformEndian = LittleEndian; /// Create an enumeration of the different /// available endianesses. +#[derive(Clone, Copy)] pub enum Endianess { /// Referes to BigEndian. @@ -52,8 +55,6 @@ macro_rules! read_bytes { ($buffer: expr, $returnType: ident, $convertFunc: ident) => ({ - use std::$returnType; - // Make sure that there is enough space to read // a value from the buffer. assert!($buffer.len() == $returnType::BYTES); @@ -69,21 +70,19 @@ macro_rules! read_bytes /// and writing them to a buffer. macro_rules! write_bytes { - ($buffer: expr, $valueType: ident, $num: expr, $convertFunc: ident) => + ($buffer: expr, $valueType: ident, $numBytes: expr, $num: expr, $convertFunc: ident) => ({ - use std::$valueType; - assert!($buffer.len() >= $valueType::BYTES, "Not enough room in the buffer to write to."); unsafe { let size: usize; - let bytes: [u8; $valueType::BYTES]; + let bytes: [u8; $numBytes]; - size = $valueType::BYTES as usize; + size = $valueType::BYTES; bytes = - mem::transmute::<_,[u8; $valueType::BYTES]>($num.$convertFunc()); + mem::transmute::<_, [u8; $numBytes]>($num.$convertFunc()); copy_nonoverlapping::((&bytes).as_ptr(), $buffer.as_mut_ptr(), size); @@ -132,17 +131,17 @@ impl Converter for BigEndian fn u16_to_bytes(buffer: &mut [u8], num: u16) { - write_bytes!(buffer, u16, num, to_be); + write_bytes!(buffer, u16, U16_BYTES, num, to_be); } fn u32_to_bytes(buffer: &mut [u8], num: u32) { - write_bytes!(buffer, u32, num, to_be); + write_bytes!(buffer, u32, U32_BYTES, num, to_be); } fn u64_to_bytes(buffer: &mut [u8], num: u64) { - write_bytes!(buffer, u64, num, to_be); + write_bytes!(buffer, u64, U64_BYTES, num, to_be); } fn usize_to_bytes(buffer: &mut [u8], num: usize) @@ -201,17 +200,17 @@ impl Converter for LittleEndian fn u16_to_bytes(buffer: &mut [u8], num: u16) { - write_bytes!(buffer, u16, num, to_le); + write_bytes!(buffer, u16, U16_BYTES, num, to_le); } fn u32_to_bytes(buffer: &mut [u8], num: u32) { - write_bytes!(buffer, u32, num, to_le); + write_bytes!(buffer, u32, U32_BYTES, num, to_le); } fn u64_to_bytes(buffer: &mut [u8], num: u64) { - write_bytes!(buffer, u64, num, to_le); + write_bytes!(buffer, u64, U64_BYTES, num, to_le); } fn usize_to_bytes(buffer: &mut [u8], num: usize) diff --git a/src/lib.rs b/src/lib.rs index c455a73..323fa0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,20 @@ -#![feature(num_bits_bytes)] +#![feature(associated_consts)] extern crate sigils; +mod byte_sized; mod converter; mod endian; mod transmutable; +pub use ::byte_sized::ByteSized; +pub use ::byte_sized::{U8_BYTES, U16_BYTES, U32_BYTES, U64_BYTES, USIZE_BYTES}; +pub use ::byte_sized::{I8_BYTES, I16_BYTES, I32_BYTES, I64_BYTES, ISIZE_BYTES}; +pub use ::byte_sized::{F32_BYTES, F64_BYTES}; pub use ::converter::Converter; pub use ::endian::{BigEndian, LittleEndian, PlatformEndian, Endianess}; pub use ::transmutable::Transmutable; diff --git a/src/transmutable.rs b/src/transmutable.rs index 0d9a575..4ab6b80 100644 --- a/src/transmutable.rs +++ b/src/transmutable.rs @@ -1,6 +1,7 @@ -use std::{u8, u16, u32, u64, usize}; -use std::{i8, i16, i32, i64, isize}; +use sigils::{Zero, Number}; +use sigils::vector::{Vector, Vector2}; +use ::byte_sized::ByteSized; use ::converter::Converter; use ::endian::{BigEndian, LittleEndian, PlatformEndian, Endianess}; @@ -126,7 +127,7 @@ impl Transmutable for u16 // the bytes for this type. assert!(buffer.len() >= u16::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u16) } } @@ -149,7 +150,7 @@ impl Transmutable for u32 // the bytes for this type. assert!(buffer.len() >= u32::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u32) } } @@ -172,7 +173,7 @@ impl Transmutable for u64 // the bytes for this type. assert!(buffer.len() >= u64::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_u64) } } @@ -195,7 +196,7 @@ impl Transmutable for usize // the bytes for this type. assert!(buffer.len() >= usize::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_usize) } } @@ -244,7 +245,7 @@ impl Transmutable for i16 // the bytes for this type. assert!(buffer.len() >= i16::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i16) } } @@ -267,7 +268,7 @@ impl Transmutable for i32 // the bytes for this type. assert!(buffer.len() >= i32::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i32) } } @@ -290,7 +291,7 @@ impl Transmutable for i64 // the bytes for this type. assert!(buffer.len() >= i64::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_i64) } } @@ -313,7 +314,7 @@ impl Transmutable for isize // the bytes for this type. assert!(buffer.len() >= isize::BYTES); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_isize) } } @@ -336,7 +337,7 @@ impl Transmutable for f32 // the bytes for this type. assert!(buffer.len() >= 4); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_f32) } } @@ -359,9 +360,51 @@ impl Transmutable for f64 // the bytes for this type. assert!(buffer.len() >= 8); - // Convert the given bytes to this type and return is. + // Convert the given bytes to this type and return it. handle_endianess_from_bytes!(buffer, endianess, bytes_to_f64) } } +impl Transmutable for Vector2 where T: Number + ByteSized + Transmutable +{ + fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess) + { + let byte_size: usize; + let num_bytes: usize; + // 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. + assert!(buffer.len() >= num_bytes); + + // Convert this to bytes and add it to the buffer. + self.x.to_bytes(&mut buffer[0..byte_size], endianess); + self.y.to_bytes(&mut buffer[byte_size..num_bytes], endianess); + } + + fn from_bytes(buffer: &[u8], endianess: Endianess) -> Vector2 + { + let byte_size: usize; + let num_bytes: usize; + let mut vec: Vector2; + + // Determine the number of bytes requires to + // represent a Vector2. + vec = Vector2::::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 + } +} diff --git a/tests/lib.rs b/tests/lib.rs index a29bbdf..311c62c 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,5 +1,4 @@ #![feature(zero_one)] -#![feature(num_bits_bytes)] extern crate rand; @@ -10,6 +9,10 @@ extern crate sigils; use std::thread::{Builder, JoinHandle}; +use alchemy::{U16_BYTES, U32_BYTES, U64_BYTES}; +use alchemy::{I16_BYTES, I32_BYTES, I64_BYTES}; +use alchemy::{USIZE_BYTES, ISIZE_BYTES}; +use alchemy::{F32_BYTES, F64_BYTES}; const EXHAUSTIVE_RUNS: u64 = 10000u64; @@ -92,7 +95,6 @@ macro_rules! full_check { fn $func_name() -> bool { - use std::$T; full_check_impl!($T, $read_func, $write_func, $T::BYTES) } }; @@ -113,8 +115,6 @@ macro_rules! overflow_impl ($numBytes: expr, $T: ident, $read_func: ident, $write_func: ident) => { - use std::num::Zero; - use alchemy::{Converter, BigEndian, LittleEndian}; @@ -166,56 +166,49 @@ macro_rules! overflow_impl macro_rules! test_buffer_overflow { ($mod_name: ident, $T: ident, - $read_func: ident, $write_func: ident) => + $read_func: ident, $write_func: ident, $numBytes: ident) => { mod $mod_name { - use std::$T; - overflow_impl!($T::BYTES, $T, $read_func, $write_func); - } - }; + use alchemy::$numBytes; + use std::num::Zero; - ($mod_name: ident, $T: ident, - $read_func: ident, $write_func: ident, $numBytes: expr) => - { - mod $mod_name - { overflow_impl!($numBytes, $T, $read_func, $write_func); } - }; + } } // Test the different data types for buffer overflow. -test_buffer_overflow!(overflow_u16, u16, bytes_to_u16, u16_to_bytes); -test_buffer_overflow!(overflow_u32, u32, bytes_to_u32, u32_to_bytes); -test_buffer_overflow!(overflow_u64, u64, bytes_to_u64, u64_to_bytes); +test_buffer_overflow!(overflow_u16, u16, bytes_to_u16, u16_to_bytes, U16_BYTES); +test_buffer_overflow!(overflow_u32, u32, bytes_to_u32, u32_to_bytes, U32_BYTES); +test_buffer_overflow!(overflow_u64, u64, bytes_to_u64, u64_to_bytes, U64_BYTES); test_buffer_overflow!(overflow_usize, usize, - bytes_to_usize, usize_to_bytes, 1); + bytes_to_usize, usize_to_bytes, U8_BYTES); -test_buffer_overflow!(overflow_i16, i16, bytes_to_i16, i16_to_bytes); -test_buffer_overflow!(overflow_i32, i32, bytes_to_i32, i32_to_bytes); -test_buffer_overflow!(overflow_i64, i64, bytes_to_i64, i64_to_bytes); +test_buffer_overflow!(overflow_i16, i16, bytes_to_i16, i16_to_bytes, I16_BYTES); +test_buffer_overflow!(overflow_i32, i32, bytes_to_i32, i32_to_bytes, I32_BYTES); +test_buffer_overflow!(overflow_i64, i64, bytes_to_i64, i64_to_bytes, I64_BYTES); test_buffer_overflow!(overflow_isize, isize, - bytes_to_isize, isize_to_bytes, 1); + bytes_to_isize, isize_to_bytes, U8_BYTES); -test_buffer_overflow!(overflow_f32, f32, bytes_to_f32, f32_to_bytes, 4); -test_buffer_overflow!(overflow_f64, f64, bytes_to_f64, f64_to_bytes, 8); +test_buffer_overflow!(overflow_f32, f32, bytes_to_f32, f32_to_bytes, F32_BYTES); +test_buffer_overflow!(overflow_f64, f64, bytes_to_f64, f64_to_bytes, F64_BYTES); // Create the exhaustive check functions for the integer types. -full_check!(check_u16, u16, bytes_to_u16, u16_to_bytes); -full_check!(check_u32, u32, bytes_to_u32, u32_to_bytes); -full_check!(check_u64, u64, bytes_to_u64, u64_to_bytes); -full_check!(check_usize, usize, bytes_to_usize, usize_to_bytes); +full_check!(check_u16, u16, bytes_to_u16, u16_to_bytes, U16_BYTES); +full_check!(check_u32, u32, bytes_to_u32, u32_to_bytes, U32_BYTES); +full_check!(check_u64, u64, bytes_to_u64, u64_to_bytes, U64_BYTES); +full_check!(check_usize, usize, bytes_to_usize, usize_to_bytes, USIZE_BYTES); -full_check!(check_i16, i16, bytes_to_i16, i16_to_bytes); -full_check!(check_i32, i32, bytes_to_i32, i32_to_bytes); -full_check!(check_i64, i64, bytes_to_i64, i64_to_bytes); -full_check!(check_isize, isize, bytes_to_isize, isize_to_bytes); +full_check!(check_i16, i16, bytes_to_i16, i16_to_bytes, I16_BYTES); +full_check!(check_i32, i32, bytes_to_i32, i32_to_bytes, I32_BYTES); +full_check!(check_i64, i64, bytes_to_i64, i64_to_bytes, I64_BYTES); +full_check!(check_isize, isize, bytes_to_isize, isize_to_bytes, ISIZE_BYTES); -full_check!(check_f32, f32, bytes_to_f32, f32_to_bytes, 4); -full_check!(check_f64, f64, bytes_to_f64, f64_to_bytes, 8); +full_check!(check_f32, f32, bytes_to_f32, f32_to_bytes, F32_BYTES); +full_check!(check_f64, f64, bytes_to_f64, f64_to_bytes, F64_BYTES); #[test]