This is trying to remove the num_bytes argument from usize/isize methods.

If num_bytes can be removed then a generic to_bytes and from_bytes
trait can be created that will help with serializing structures
and generic data.
This commit is contained in:
Jason Travis Smith 2016-01-02 14:54:03 -05:00
parent a3cc3a3515
commit 6a623932ed
4 changed files with 92 additions and 45 deletions

19
.gitignore vendored
View File

@ -1,2 +1,17 @@
target # Ignore swap files from text editors.
Cargo.lock *.swp
# Ignore compiled files.
*.o
*.so
*.rlib
*.dll
*.exe
# Ignore files/directories generated by Cargo.
/target/
# Remove Cargo.lock from gitignore if creating an executable,
# leave it for libraries.
# More information here: http://doc.crates.io/guide.html#cargotoml-vs-cargolock
#Cargo.lock

12
Cargo.lock generated Normal file
View File

@ -0,0 +1,12 @@
[root]
name = "alchemy"
version = "0.1.0"
dependencies = [
"sigils 0.1.0 (git+https://gitlab.com/CyberMages/sigils.git)",
]
[[package]]
name = "sigils"
version = "0.1.0"
source = "git+https://gitlab.com/CyberMages/sigils.git#a618fb27f7ceaaa3f75b334dd8ec716ff795273a"

View File

@ -32,14 +32,14 @@ pub type PlatformEndian = LittleEndian;
/// and turning them into the requested type. /// and turning them into the requested type.
macro_rules! read_bytes macro_rules! read_bytes
{ {
($buffer: expr, $return_type: ident, $convert_func: ident) => ($buffer: expr, $returnType: ident, $convertFunc: ident) =>
({ ({
use std::$return_type; use std::$returnType;
assert!($return_type::BYTES <= $buffer.len()); assert!($returnType::BYTES <= $buffer.len());
unsafe unsafe
{ {
(*($buffer.as_ptr() as *const $return_type)).$convert_func() (*($buffer.as_ptr() as *const $returnType)).$convertFunc()
} }
}) })
} }
@ -48,21 +48,23 @@ macro_rules! read_bytes
/// and writing them to a buffer. /// and writing them to a buffer.
macro_rules! write_bytes macro_rules! write_bytes
{ {
($buffer: expr, $value_type: ident, $num: expr, $convert_func: ident) => ($buffer: expr, $valueType: ident, $num: expr, $convertFunc: ident) =>
({ ({
use std::$value_type; use std::$valueType;
assert!($value_type::BYTES <= $buffer.len()); assert!($valueType::BYTES <= $buffer.len());
unsafe unsafe
{ {
let size: usize; let size: usize;
let bytes: [u8; $value_type::BYTES]; let bytes: [u8; $valueType::BYTES];
size = $value_type::BYTES as usize; size = $valueType::BYTES as usize;
bytes = bytes =
mem::transmute::<_,[u8; $value_type::BYTES]>($num.$convert_func()); mem::transmute::<_,[u8; $valueType::BYTES]>($num.$convertFunc());
copy_nonoverlapping((&bytes).as_ptr(), $buffer.as_mut_ptr(), size); copy_nonoverlapping::<u8>((&bytes).as_ptr(),
$buffer.as_mut_ptr(),
size);
} }
}) })
} }
@ -86,21 +88,20 @@ impl Transmutable for BigEndian
read_bytes!(buffer, u64, to_be) read_bytes!(buffer, u64, to_be)
} }
fn bytes_to_usize(buffer: &[u8], num_bytes: u8) -> usize fn bytes_to_usize(buffer: &[u8]) -> usize
{ {
let mut out: [u8; 8]; let mut out: [u8; 8];
let ptr_out: *mut u8; let ptr_out: *mut u8;
assert!(1 <= num_bytes && num_bytes <= 8); assert!(1 <= buffer.len() && buffer.len() <= 8);
assert!(num_bytes as usize <= buffer.len());
out = [0u8; 8]; out = [0u8; 8];
ptr_out = out.as_mut_ptr(); ptr_out = out.as_mut_ptr();
unsafe unsafe
{ {
copy_nonoverlapping(buffer.as_ptr(), copy_nonoverlapping::<u8>(buffer.as_ptr(),
ptr_out.offset((8 - num_bytes) as isize), ptr_out.offset((8 - buffer.len()) as isize),
num_bytes as usize); buffer.len());
(*(ptr_out as *const u64)).to_be() as usize (*(ptr_out as *const u64)).to_be() as usize
} }
@ -122,17 +123,20 @@ impl Transmutable for BigEndian
write_bytes!(buffer, u64, num, to_be); write_bytes!(buffer, u64, num, to_be);
} }
fn usize_to_bytes(buffer: &mut [u8], num: usize, num_bytes: u8) fn usize_to_bytes(buffer: &mut [u8], num: usize)
{ {
let bytes: [u8; 8]; let bytes: [u8; 8];
let num_bytes: u8;
num_bytes = buffer.len() as u8;
assert!(determine_size(num as u64) <= num_bytes && num_bytes <= 8); assert!(determine_size(num as u64) <= num_bytes && num_bytes <= 8);
assert!(num_bytes as usize <= buffer.len());
unsafe unsafe
{ {
bytes = mem::transmute::<usize, [u8; 8]>(num.to_be()); bytes = mem::transmute::<usize, [u8; 8]>(num.to_be());
copy_nonoverlapping(bytes.as_ptr().offset((8 - num_bytes) as isize), copy_nonoverlapping::<u8>(
bytes.as_ptr().offset((8 - num_bytes) as isize),
buffer.as_mut_ptr(), num_bytes as usize); buffer.as_mut_ptr(), num_bytes as usize);
} }
} }
@ -155,19 +159,18 @@ impl Transmutable for LittleEndian
read_bytes!(buffer, u64, to_le) read_bytes!(buffer, u64, to_le)
} }
fn bytes_to_usize(buffer: &[u8], num_bytes: u8) -> usize fn bytes_to_usize(buffer: &[u8]) -> usize
{ {
let mut out: [u8; 8]; let mut out: [u8; 8];
let ptr_out: *mut u8; let ptr_out: *mut u8;
assert!(1 <= num_bytes && num_bytes <= 8); assert!(1 <= buffer.len() && buffer.len() <= 8);
assert!(num_bytes as usize <= buffer.len());
out = [0u8; 8]; out = [0u8; 8];
ptr_out = out.as_mut_ptr(); ptr_out = out.as_mut_ptr();
unsafe unsafe
{ {
copy_nonoverlapping(buffer.as_ptr(), ptr_out, num_bytes as usize); copy_nonoverlapping::<u8>(buffer.as_ptr(), ptr_out, buffer.len());
(*(ptr_out as *const u64)).to_le() as usize (*(ptr_out as *const u64)).to_le() as usize
} }
} }
@ -188,17 +191,19 @@ impl Transmutable for LittleEndian
write_bytes!(buffer, u64, num, to_le); write_bytes!(buffer, u64, num, to_le);
} }
fn usize_to_bytes(buffer: &mut [u8], num: usize, num_bytes: u8) fn usize_to_bytes(buffer: &mut [u8], num: usize)
{ {
let bytes: [u8; 8]; let bytes: [u8; 8];
let num_bytes: u8;
num_bytes = buffer.len() as u8;
assert!(determine_size(num as u64) <= num_bytes && num_bytes <= 8); assert!(determine_size(num as u64) <= num_bytes && num_bytes <= 8);
assert!(num_bytes as usize <= buffer.len());
unsafe unsafe
{ {
bytes = mem::transmute::<usize, [u8; 8]>(num.to_le()); bytes = mem::transmute::<usize, [u8; 8]>(num.to_le());
copy_nonoverlapping(bytes.as_ptr(), buffer.as_mut_ptr(), copy_nonoverlapping::<u8>(bytes.as_ptr(), buffer.as_mut_ptr(),
num_bytes as usize); num_bytes as usize);
} }
} }

View File

@ -45,15 +45,14 @@ pub trait Transmutable
/// ///
/// This will panic if the number of bytes /// This will panic if the number of bytes
/// passed in is less than one or more than eight. /// passed in is less than one or more than eight.
fn bytes_to_isize(buffer: &[u8], num_bytes: u8) -> isize fn bytes_to_isize(buffer: &[u8]) -> isize
{ {
let temp_num: u64; let temp_num: u64;
assert!(num_bytes > 1 && num_bytes < 8); assert!(buffer.len() > 1 && buffer.len() < 8);
assert!(buffer.len() < (num_bytes as usize));
temp_num = Self::bytes_to_usize(buffer, num_bytes) as u64; temp_num = Self::bytes_to_usize(buffer) as u64;
add_sign(temp_num, num_bytes) as isize add_sign(temp_num, buffer.len() as u8) as isize
} }
/// Converts an array of bytes to a 32-bit floating point number. /// Converts an array of bytes to a 32-bit floating point number.
@ -126,15 +125,14 @@ pub trait Transmutable
/// This will panic if the number of bytes /// This will panic if the number of bytes
/// passed in is less than the byte size of the given number /// passed in is less than the byte size of the given number
/// or more than eight. /// or more than eight.
fn isize_to_bytes(buffer: &mut [u8], num: isize, num_bytes: u8) fn isize_to_bytes(buffer: &mut [u8], num: isize)
{ {
let temp_num: usize; let temp_num: usize;
assert!(num_bytes > 1 && num_bytes < 8); assert!(buffer.len() > 1 && buffer.len() < 8);
assert!(buffer.len() < (num_bytes as usize));
temp_num = remove_sign(num as i64, num_bytes) as usize; temp_num = remove_sign(num as i64, buffer.len() as u8) as usize;
Self::usize_to_bytes(buffer, temp_num, num_bytes) Self::usize_to_bytes(buffer, temp_num)
} }
/// Converts a 32-bit floating point number to bytes /// Converts a 32-bit floating point number to bytes
@ -196,7 +194,7 @@ pub trait Transmutable
/// ///
/// This will panic if the number of bytes /// This will panic if the number of bytes
/// passed in is less than one or more than eight. /// passed in is less than one or more than eight.
fn bytes_to_usize(buffer: &[u8], num_bytes: u8) -> usize; fn bytes_to_usize(buffer: &[u8]) -> usize;
/// Converts an unsigned 16-bit integer to bytes /// Converts an unsigned 16-bit integer to bytes
@ -233,7 +231,7 @@ pub trait Transmutable
/// This will panic if the number of bytes /// This will panic if the number of bytes
/// passed in is less than the byte size of the given number /// passed in is less than the byte size of the given number
/// or more than eight. /// or more than eight.
fn usize_to_bytes(buffer: &mut [u8], num: usize, num_bytes: u8); fn usize_to_bytes(buffer: &mut [u8], num: usize);
} }
@ -258,3 +256,20 @@ fn remove_sign(val: i64, num_bytes: u8) -> u64
shift = (8 - num_bytes) * 8; shift = (8 - num_bytes) * 8;
(val << shift) as u64 >> shift (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;
}