The conversion of an Array of bytes to a value can now fail gracefully.
This was added so that parsers can detect problems converting a value and fail in an expected way.
This commit is contained in:
@ -17,6 +17,12 @@ convert_sigils = ["sigils"]
|
||||
[dependencies.scribe]
|
||||
git = "ssh://git@gitlab.com/CyberMages/Core/scribe.git"
|
||||
|
||||
[dependencies.weave]
|
||||
git = "ssh://git@gitlab.com/CyberMages/Core/weave.git"
|
||||
|
||||
[dependencies.spellbook]
|
||||
git = "ssh://git@gitlab.com/CyberMages/Core/spellbook.git"
|
||||
|
||||
[dependencies.sigils]
|
||||
git = "ssh://git@gitlab.com/CyberMages/Core/sigils.git"
|
||||
optional = true
|
||||
|
@ -1,7 +1,9 @@
|
||||
extern crate weave;
|
||||
extern crate alchemy;
|
||||
|
||||
|
||||
|
||||
use weave::Error;
|
||||
use alchemy::{Converter, Endianess, PlatformEndian, Transmutable};
|
||||
|
||||
|
||||
@ -9,7 +11,6 @@ use alchemy::{Converter, Endianess, PlatformEndian, Transmutable};
|
||||
fn use_converter()
|
||||
{
|
||||
let num: f32;
|
||||
let final_num: f32;
|
||||
let mut buffer: Vec<u8>;
|
||||
|
||||
// Initialize the variables.
|
||||
@ -25,14 +26,23 @@ fn use_converter()
|
||||
println!("Buffer contains: {}", stringify_array(buffer.as_slice()));
|
||||
|
||||
// Convert the array of bytes into a floating point number.
|
||||
final_num = PlatformEndian::bytes_to_f32(buffer.as_slice());
|
||||
match PlatformEndian::bytes_to_f32(buffer.as_slice())
|
||||
{
|
||||
Ok(final_num) =>
|
||||
{
|
||||
println!("The buffer converts back to: {}", final_num);
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
println!("{}\n{}", error, error.get_description());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_transmutable()
|
||||
{
|
||||
let num: f32;
|
||||
let final_num: f32;
|
||||
let endianess: Endianess;
|
||||
let mut buffer: Vec<u8>;
|
||||
|
||||
@ -50,8 +60,18 @@ pub fn use_transmutable()
|
||||
println!("Buffer contains: {}", stringify_array(buffer.as_slice()));
|
||||
|
||||
// Convert the array of bytes into a floating point number.
|
||||
final_num = f32::from_endian_bytes(buffer.as_slice(), endianess);
|
||||
match f32::from_endian_bytes(buffer.as_slice(), endianess)
|
||||
{
|
||||
Ok(final_num) =>
|
||||
{
|
||||
println!("The buffer converts back to: {}", final_num);
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
println!("{}\n{}", error, error.get_description());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This just help pretty up the printing of an array of bytes.
|
||||
|
@ -1,10 +1,16 @@
|
||||
//! Run this example with --feature convert_sigils
|
||||
|
||||
extern crate weave;
|
||||
extern crate alchemy;
|
||||
extern crate sigils;
|
||||
|
||||
|
||||
|
||||
use weave::Error;
|
||||
|
||||
use alchemy::F64_BYTES;
|
||||
use alchemy::{Endianess, Transmutable};
|
||||
|
||||
use sigils::quaternion::Quaternion;
|
||||
|
||||
|
||||
@ -58,7 +64,6 @@ fn stringify_array(buffer: &[u8]) -> String
|
||||
pub fn main()
|
||||
{
|
||||
let quat: Quaternion<f64>;
|
||||
let final_quat: Quaternion<f64>;
|
||||
let endianess: Endianess;
|
||||
let mut buffer: Vec<u8>;
|
||||
|
||||
@ -79,6 +84,16 @@ pub fn main()
|
||||
println!("Buffer contains: {}", stringify_array(buffer.as_slice()));
|
||||
|
||||
// Convert the array of bytes into a Vector2.
|
||||
final_quat = Quaternion::from_endian_bytes(buffer.as_slice(), endianess);
|
||||
match Quaternion::<f64>::from_endian_bytes(buffer.as_slice(), endianess)
|
||||
{
|
||||
Ok(final_quat) =>
|
||||
{
|
||||
println!("The buffer converts back to: {}", final_quat);
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
println!("{}\n{}", error, error.get_description());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
extern crate weave;
|
||||
|
||||
extern crate alchemy;
|
||||
|
||||
|
||||
|
||||
use weave::Error;
|
||||
|
||||
use alchemy::{Converter, Endianess, PlatformEndian, Transmutable};
|
||||
use alchemy::platform_to_network_order;
|
||||
|
||||
@ -9,7 +14,6 @@ use alchemy::platform_to_network_order;
|
||||
fn use_converter()
|
||||
{
|
||||
let num: u16;
|
||||
let final_num: u16;
|
||||
let mut buffer: Vec<u8>;
|
||||
|
||||
// Initialize the variables.
|
||||
@ -25,14 +29,23 @@ fn use_converter()
|
||||
println!("Buffer contains: {}", stringify_array(buffer.as_slice()));
|
||||
|
||||
// Convert the array of bytes into a short number.
|
||||
final_num = PlatformEndian::bytes_to_u16(buffer.as_slice());
|
||||
match PlatformEndian::bytes_to_u16(buffer.as_slice())
|
||||
{
|
||||
Ok(final_num) =>
|
||||
{
|
||||
println!("The buffer converts back to: {}", final_num);
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
println!("{}\n{}", error, error.get_description());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_transmutable()
|
||||
{
|
||||
let num: u16;
|
||||
let final_num: u16;
|
||||
let endianess: Endianess;
|
||||
let mut buffer: Vec<u8>;
|
||||
|
||||
@ -50,8 +63,19 @@ pub fn use_transmutable()
|
||||
println!("Buffer contains: {}", stringify_array(buffer.as_slice()));
|
||||
|
||||
// Convert the array of bytes into a short number.
|
||||
final_num = u16::from_endian_bytes(buffer.as_slice(), endianess);
|
||||
match u16::from_endian_bytes(buffer.as_slice(), endianess)
|
||||
{
|
||||
Ok(final_num) =>
|
||||
{
|
||||
println!("The buffer converts back to: {}", final_num);
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
println!("{}\n{}", error, error.get_description());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// This just help pretty up the printing of an array of bytes.
|
||||
@ -105,6 +129,9 @@ pub fn main()
|
||||
|
||||
println!("");
|
||||
|
||||
println!("This turns into a network value of: {}",
|
||||
platform_to_network_order(32832u16));
|
||||
match platform_to_network_order(32832u16)
|
||||
{
|
||||
Ok(val) => { println!("This turns into a network value of: {}", val); }
|
||||
Err(error) => { println!("{}\n{}", error, error.get_description()); }
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
extern crate weave;
|
||||
extern crate alchemy;
|
||||
extern crate sigils;
|
||||
|
||||
|
||||
|
||||
use weave::Error;
|
||||
|
||||
use alchemy::U64_BYTES;
|
||||
use alchemy::{Endianess, Transmutable};
|
||||
|
||||
use sigils::vector::Vector2;
|
||||
|
||||
|
||||
@ -58,7 +62,6 @@ fn stringify_array(buffer: &[u8]) -> String
|
||||
pub fn main()
|
||||
{
|
||||
let vec: Vector2<u64>;
|
||||
let final_vec: Vector2<u64>;
|
||||
let endianess: Endianess;
|
||||
let mut buffer: Vec<u8>;
|
||||
|
||||
@ -79,6 +82,16 @@ pub fn main()
|
||||
println!("Buffer contains: {}", stringify_array(buffer.as_slice()));
|
||||
|
||||
// Convert the array of bytes into a Vector2.
|
||||
final_vec = Vector2::from_endian_bytes(buffer.as_slice(), endianess);
|
||||
match Vector2::<u64>::from_endian_bytes(buffer.as_slice(), endianess)
|
||||
{
|
||||
Ok(final_vec) =>
|
||||
{
|
||||
println!("The buffer converts back to: {}", final_vec);
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
println!("{}\n{}", error, error.get_description());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,14 +73,6 @@ pub trait ByteSized
|
||||
|
||||
/// The amount of bytes it takes to represent this type.
|
||||
const BYTES: usize;
|
||||
|
||||
|
||||
|
||||
/// The amount of bits it takes to represent this type.
|
||||
fn get_bit_size() -> usize;
|
||||
|
||||
/// The amount of bytes it takes to represent this type.
|
||||
fn get_byte_size() -> usize;
|
||||
}
|
||||
|
||||
|
||||
@ -93,18 +85,6 @@ macro_rules! byte_sized_impl
|
||||
{
|
||||
const BITS: usize = $numBytes * 8;
|
||||
const BYTES: usize = $numBytes;
|
||||
|
||||
|
||||
|
||||
fn get_bit_size() -> usize
|
||||
{
|
||||
Self::BITS
|
||||
}
|
||||
|
||||
fn get_byte_size() -> usize
|
||||
{
|
||||
Self::BYTES
|
||||
}
|
||||
}
|
||||
)*}
|
||||
}
|
||||
|
76
src/conversion_error.rs
Normal file
76
src/conversion_error.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use weave::Error;
|
||||
|
||||
|
||||
|
||||
/// The errors that may occur during conversion from an array of bytes
|
||||
/// to an actual value.
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum ConversionError
|
||||
{
|
||||
/// There were not enough bytes to create the desired type.
|
||||
TooFewBytes,
|
||||
|
||||
/// There were to many bytes to create the desired type.
|
||||
TooManyBytes
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Error for ConversionError
|
||||
{
|
||||
fn get_description(&self) -> &str
|
||||
{
|
||||
match *self
|
||||
{
|
||||
ConversionError::TooFewBytes =>
|
||||
{
|
||||
"Not enough bytes of data were provided \
|
||||
to properly create this type."
|
||||
}
|
||||
|
||||
ConversionError::TooManyBytes =>
|
||||
{
|
||||
"Too many bytes of data were provided \
|
||||
to properly create this type."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_cause(&self) -> Option<&Error>
|
||||
{
|
||||
match *self
|
||||
{
|
||||
_ =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for ConversionError
|
||||
{
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
||||
{
|
||||
::std::fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for ConversionError
|
||||
{
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
||||
{
|
||||
match *self
|
||||
{
|
||||
ConversionError::TooFewBytes =>
|
||||
{
|
||||
write!(f, "Byte Conversion Error: TooFewBytes")
|
||||
}
|
||||
|
||||
ConversionError::TooManyBytes =>
|
||||
{
|
||||
write!(f, "Byte Conversion Error: TooManyBytes")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
use std::mem;
|
||||
|
||||
use ::byte_sized::ByteSized;
|
||||
use spellbook::components::Array;
|
||||
|
||||
use ::byte_sized::ByteSized;
|
||||
use ::conversion_error::ConversionError;
|
||||
|
||||
|
||||
/// Describes types that can convert Numbers into bytes,
|
||||
@ -13,9 +15,9 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough information to convert.
|
||||
fn bytes_to_i16(buffer: &[u8]) -> i16
|
||||
fn bytes_to_i16(buffer: &[u8]) -> Result<i16, ConversionError>
|
||||
{
|
||||
Self::bytes_to_u16(buffer) as i16
|
||||
Ok(try!(Self::bytes_to_u16(buffer)) as i16)
|
||||
}
|
||||
|
||||
/// Converts an array of bytes to a signed 32-bit integer.
|
||||
@ -23,9 +25,9 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough information to convert.
|
||||
fn bytes_to_i32(buffer: &[u8]) -> i32
|
||||
fn bytes_to_i32(buffer: &[u8]) -> Result<i32, ConversionError>
|
||||
{
|
||||
Self::bytes_to_u32(buffer) as i32
|
||||
Ok(try!(Self::bytes_to_u32(buffer)) as i32)
|
||||
}
|
||||
|
||||
/// Converts an array of bytes to a signed 64-bit integer.
|
||||
@ -33,9 +35,9 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough information to convert.
|
||||
fn bytes_to_i64(buffer: &[u8]) -> i64
|
||||
fn bytes_to_i64(buffer: &[u8]) -> Result<i64, ConversionError>
|
||||
{
|
||||
Self::bytes_to_u64(buffer) as i64
|
||||
Ok(try!(Self::bytes_to_u64(buffer)) as i64)
|
||||
}
|
||||
|
||||
/// Converts an array of bytes to a signed integer.
|
||||
@ -44,16 +46,16 @@ pub trait Converter
|
||||
/// 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
|
||||
/// This will panic if the buffer is given too
|
||||
/// much data to convert. [isize::BYTES, u64::BYTES]
|
||||
fn bytes_to_isize(buffer: &[u8]) -> Result<isize, ConversionError>
|
||||
{
|
||||
let temp_num: u64;
|
||||
|
||||
assert!(buffer.len() >= 1 && buffer.len() <= 8);
|
||||
check_length!(buffer, isize::BYTES, u64::BYTES);
|
||||
|
||||
temp_num = Self::bytes_to_usize(buffer) as u64;
|
||||
add_sign(temp_num, buffer.len() as u8) as isize
|
||||
temp_num = try!(Self::bytes_to_usize(buffer)) as u64;
|
||||
Ok(add_sign(temp_num, buffer.len() as u8) as isize)
|
||||
}
|
||||
|
||||
/// Converts an array of bytes to a 32-bit floating point number.
|
||||
@ -61,11 +63,11 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough information to convert.
|
||||
fn bytes_to_f32(buffer: &[u8]) -> f32
|
||||
fn bytes_to_f32(buffer: &[u8]) -> Result<f32, ConversionError>
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
mem::transmute::<u32, f32>(Self::bytes_to_u32(buffer))
|
||||
Ok(mem::transmute::<u32, f32>(try!(Self::bytes_to_u32(buffer))))
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,11 +76,11 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough information to convert.
|
||||
fn bytes_to_f64(buffer: &[u8]) -> f64
|
||||
fn bytes_to_f64(buffer: &[u8]) -> Result<f64, ConversionError>
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
mem::transmute::<u64, f64>(Self::bytes_to_u64(buffer))
|
||||
Ok(mem::transmute::<u64, f64>(try!(Self::bytes_to_u64(buffer))))
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +91,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn i16_to_bytes(num: i16) -> Vec<u8>
|
||||
fn i16_to_bytes(num: i16) -> Array<u8>
|
||||
{
|
||||
Self::u16_to_bytes(num as u16)
|
||||
}
|
||||
@ -100,7 +102,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn i32_to_bytes(num: i32) -> Vec<u8>
|
||||
fn i32_to_bytes(num: i32) -> Array<u8>
|
||||
{
|
||||
Self::u32_to_bytes(num as u32)
|
||||
}
|
||||
@ -111,7 +113,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn i64_to_bytes(num: i64) -> Vec<u8>
|
||||
fn i64_to_bytes(num: i64) -> Array<u8>
|
||||
{
|
||||
Self::u64_to_bytes(num as u64)
|
||||
}
|
||||
@ -126,7 +128,7 @@ pub trait Converter
|
||||
/// 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(num: isize) -> Vec<u8>
|
||||
fn isize_to_bytes(num: isize) -> Array<u8>
|
||||
{
|
||||
let temp_num: usize;
|
||||
|
||||
@ -140,7 +142,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn f32_to_bytes(num: f32) -> Vec<u8>
|
||||
fn f32_to_bytes(num: f32) -> Array<u8>
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
@ -154,7 +156,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn f64_to_bytes(num: f64) -> Vec<u8>
|
||||
fn f64_to_bytes(num: f64) -> Array<u8>
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
@ -169,21 +171,21 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough information to convert.
|
||||
fn bytes_to_u16(buffer: &[u8]) -> u16;
|
||||
fn bytes_to_u16(buffer: &[u8]) -> Result<u16, ConversionError>;
|
||||
|
||||
/// 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;
|
||||
fn bytes_to_u32(buffer: &[u8]) -> Result<u32, ConversionError>;
|
||||
|
||||
/// 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;
|
||||
fn bytes_to_u64(buffer: &[u8]) -> Result<u64, ConversionError>;
|
||||
|
||||
/// Converts an array of bytes to an unsigned integer.
|
||||
///
|
||||
@ -193,7 +195,7 @@ pub trait Converter
|
||||
///
|
||||
/// 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;
|
||||
fn bytes_to_usize(buffer: &[u8]) -> Result<usize, ConversionError>;
|
||||
|
||||
|
||||
/// Converts an unsigned 16-bit integer to bytes
|
||||
@ -202,7 +204,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn u16_to_bytes(num: u16) -> Vec<u8>;
|
||||
fn u16_to_bytes(num: u16) -> Array<u8>;
|
||||
|
||||
/// Converts an unsigned 32-bit integer to bytes
|
||||
/// and places them into the given buffer.
|
||||
@ -210,7 +212,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn u32_to_bytes(num: u32) -> Vec<u8>;
|
||||
fn u32_to_bytes(num: u32) -> Array<u8>;
|
||||
|
||||
/// Converts an unsigned 64-bit integer to bytes
|
||||
/// and places them into the given buffer.
|
||||
@ -218,7 +220,7 @@ pub trait Converter
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
fn u64_to_bytes(num: u64) -> Vec<u8>;
|
||||
fn u64_to_bytes(num: u64) -> Array<u8>;
|
||||
|
||||
/// Converts an unsigned integer to bytes
|
||||
/// and places them into the given buffer.
|
||||
@ -230,7 +232,7 @@ pub trait Converter
|
||||
/// 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(num: usize) -> Vec<u8>;
|
||||
fn usize_to_bytes(num: usize) -> Array<u8>;
|
||||
|
||||
|
||||
/// Converts a String to bytes
|
||||
@ -243,14 +245,14 @@ pub trait Converter
|
||||
/// This will panic if the number of bytes
|
||||
/// passed in is less than the byte size of
|
||||
/// the given String.
|
||||
fn bytes_to_string(buffer: &[u8]) -> String;
|
||||
fn bytes_to_string(buffer: &[u8]) -> Result<String, ConversionError>;
|
||||
|
||||
/// Converts an array of bytes to a String.
|
||||
///
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough information to convert.
|
||||
fn string_to_bytes(string: String) -> Vec<u8>;
|
||||
fn string_to_bytes(string: String) -> Array<u8>;
|
||||
}
|
||||
|
||||
|
||||
|
125
src/endian.rs
125
src/endian.rs
@ -1,5 +1,8 @@
|
||||
use spellbook::components::Array;
|
||||
|
||||
use ::byte_sized::ByteSized;
|
||||
use ::byte_sized::U64_BYTES;
|
||||
use ::conversion_error::ConversionError;
|
||||
use ::converter::Converter;
|
||||
use ::transmutable::Transmutable;
|
||||
|
||||
@ -76,7 +79,7 @@ macro_rules! read_bytes
|
||||
({
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!($buffer.len() == $returnType::BYTES);
|
||||
check_length!($buffer == $returnType::BYTES);
|
||||
|
||||
unsafe
|
||||
{
|
||||
@ -107,79 +110,60 @@ macro_rules! write_bytes
|
||||
|
||||
impl Converter for BigEndian
|
||||
{
|
||||
fn bytes_to_u16(buffer: &[u8]) -> u16
|
||||
fn bytes_to_u16(buffer: &[u8]) -> Result<u16, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == u16::BYTES);
|
||||
|
||||
pack_big_endian!(buffer, u16, u16::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_u32(buffer: &[u8]) -> u32
|
||||
fn bytes_to_u32(buffer: &[u8]) -> Result<u32, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == u32::BYTES);
|
||||
|
||||
pack_big_endian!(buffer, u32, u32::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_u64(buffer: &[u8]) -> u64
|
||||
fn bytes_to_u64(buffer: &[u8]) -> Result<u64, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == u64::BYTES);
|
||||
|
||||
pack_big_endian!(buffer, u64, u64::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_usize(buffer: &[u8]) -> usize
|
||||
fn bytes_to_usize(buffer: &[u8]) -> Result<usize, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == usize::BYTES);
|
||||
|
||||
pack_big_endian!(buffer, usize, usize::BYTES)
|
||||
}
|
||||
|
||||
|
||||
fn u16_to_bytes(num: u16) -> Vec<u8>
|
||||
fn u16_to_bytes(num: u16) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_big_endian!(num, u16::BYTES)
|
||||
}
|
||||
|
||||
fn u32_to_bytes(num: u32) -> Vec<u8>
|
||||
fn u32_to_bytes(num: u32) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_big_endian!(num, u32::BYTES)
|
||||
}
|
||||
|
||||
fn u64_to_bytes(num: u64) -> Vec<u8>
|
||||
fn u64_to_bytes(num: u64) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_big_endian!(num, u64::BYTES)
|
||||
}
|
||||
|
||||
fn usize_to_bytes(num: usize) -> Vec<u8>
|
||||
fn usize_to_bytes(num: usize) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_big_endian!(num, usize::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_string(buffer: &[u8]) -> String
|
||||
fn bytes_to_string(buffer: &[u8]) -> Result<String, ConversionError>
|
||||
{
|
||||
let byte_count: u64;
|
||||
let new_string: String;
|
||||
|
||||
// A string array should have atleast a u64 size byte count.
|
||||
assert!(buffer.len() >= U64_BYTES);
|
||||
|
||||
// Strings start with the size of bytes to read as
|
||||
// a u64. So read that in and then we know how many
|
||||
// bytes make up the string.
|
||||
byte_count = BigEndian::bytes_to_u64(&buffer[0..U64_BYTES]);
|
||||
byte_count = try!(BigEndian::bytes_to_u64(&buffer[0..U64_BYTES]));
|
||||
|
||||
if byte_count > 0
|
||||
{
|
||||
@ -201,14 +185,14 @@ impl Converter for BigEndian
|
||||
new_string = String::new();
|
||||
}
|
||||
|
||||
new_string
|
||||
Ok(new_string)
|
||||
}
|
||||
|
||||
fn string_to_bytes(string: String) -> Vec<u8>
|
||||
fn string_to_bytes(string: String) -> Array<u8>
|
||||
{
|
||||
let bytes: &[u8];
|
||||
let byte_count: u64;
|
||||
let mut buffer: Vec<u8>;
|
||||
let mut buffer: Array<u8>;
|
||||
|
||||
// Turn the string into a byte array.
|
||||
bytes = string.as_bytes();
|
||||
@ -218,7 +202,7 @@ impl Converter for BigEndian
|
||||
byte_count = bytes.len() as u64;
|
||||
|
||||
// Make sure the buffer has enough space for this string.
|
||||
buffer = Vec::with_capacity(bytes.len() + U64_BYTES);
|
||||
buffer = Array::with_capacity(bytes.len() + U64_BYTES);
|
||||
|
||||
// Add the count to the buffer.
|
||||
buffer.append(&mut BigEndian::u64_to_bytes(byte_count));
|
||||
@ -235,79 +219,60 @@ impl Converter for BigEndian
|
||||
|
||||
impl Converter for LittleEndian
|
||||
{
|
||||
fn bytes_to_u16(buffer: &[u8]) -> u16
|
||||
fn bytes_to_u16(buffer: &[u8]) -> Result<u16, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == u16::BYTES);
|
||||
|
||||
pack_little_endian!(buffer, u16, u16::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_u32(buffer: &[u8]) -> u32
|
||||
fn bytes_to_u32(buffer: &[u8]) -> Result<u32, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == u32::BYTES);
|
||||
|
||||
pack_little_endian!(buffer, u32, u32::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_u64(buffer: &[u8]) -> u64
|
||||
fn bytes_to_u64(buffer: &[u8]) -> Result<u64, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == u64::BYTES);
|
||||
|
||||
pack_little_endian!(buffer, u64, u64::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_usize(buffer: &[u8]) -> usize
|
||||
fn bytes_to_usize(buffer: &[u8]) -> Result<usize, ConversionError>
|
||||
{
|
||||
// Make sure that there is enough space to read
|
||||
// a value from the buffer.
|
||||
assert!(buffer.len() == usize::BYTES);
|
||||
|
||||
pack_little_endian!(buffer, usize, usize::BYTES)
|
||||
}
|
||||
|
||||
|
||||
fn u16_to_bytes(num: u16) -> Vec<u8>
|
||||
fn u16_to_bytes(num: u16) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_little_endian!(num, u16::BYTES)
|
||||
}
|
||||
|
||||
fn u32_to_bytes(num: u32) -> Vec<u8>
|
||||
fn u32_to_bytes(num: u32) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_little_endian!(num, u32::BYTES)
|
||||
}
|
||||
|
||||
fn u64_to_bytes(num: u64) -> Vec<u8>
|
||||
fn u64_to_bytes(num: u64) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_little_endian!(num, u64::BYTES)
|
||||
}
|
||||
|
||||
fn usize_to_bytes(num: usize) -> Vec<u8>
|
||||
fn usize_to_bytes(num: usize) -> Array<u8>
|
||||
{
|
||||
// Unpack the value into it's byte form.
|
||||
unpack_little_endian!(num, usize::BYTES)
|
||||
}
|
||||
|
||||
fn bytes_to_string(buffer: &[u8]) -> String
|
||||
fn bytes_to_string(buffer: &[u8]) -> Result<String, ConversionError>
|
||||
{
|
||||
let byte_count: u64;
|
||||
let new_string: String;
|
||||
|
||||
// A string array should have atleast a u64 size byte count.
|
||||
assert!(buffer.len() >= U64_BYTES);
|
||||
|
||||
// Strings start with the size of bytes to read as
|
||||
// a u64. So read that in and then we know how many
|
||||
// bytes make up the string.
|
||||
byte_count = LittleEndian::bytes_to_u64(&buffer[0..U64_BYTES]);
|
||||
byte_count = try!(LittleEndian::bytes_to_u64(&buffer[0..U64_BYTES]));
|
||||
|
||||
if byte_count > 0
|
||||
{
|
||||
@ -329,14 +294,14 @@ impl Converter for LittleEndian
|
||||
new_string = String::new();
|
||||
}
|
||||
|
||||
new_string
|
||||
Ok(new_string)
|
||||
}
|
||||
|
||||
fn string_to_bytes(string: String) -> Vec<u8>
|
||||
fn string_to_bytes(string: String) -> Array<u8>
|
||||
{
|
||||
let bytes: &[u8];
|
||||
let byte_count: u64;
|
||||
let mut buffer: Vec<u8>;
|
||||
let mut buffer: Array<u8>;
|
||||
|
||||
// Turn the string into a byte array.
|
||||
bytes = string.as_bytes();
|
||||
@ -346,7 +311,7 @@ impl Converter for LittleEndian
|
||||
byte_count = bytes.len() as u64;
|
||||
|
||||
// Make sure the buffer has enough space for this string.
|
||||
buffer = Vec::with_capacity(bytes.len() + U64_BYTES);
|
||||
buffer = Array::with_capacity(bytes.len() + U64_BYTES);
|
||||
|
||||
// Add the count to the buffer.
|
||||
buffer.append(&mut LittleEndian::u64_to_bytes(byte_count));
|
||||
@ -401,37 +366,47 @@ impl ::std::fmt::Display for Endianess
|
||||
|
||||
|
||||
/// Turns a Network order value to a Platform order value.
|
||||
pub fn network_to_platform_order<T>(val: T) -> T
|
||||
pub fn network_to_platform_order<T>(val: T) -> Result<T, ConversionError>
|
||||
where T: Transmutable
|
||||
{
|
||||
let converted_val: T;
|
||||
|
||||
// Determine what endianess the Platform is using.
|
||||
if cfg!(target_endian="big")
|
||||
if cfg!(target_endian = "big")
|
||||
{
|
||||
// Network endianess is Big endian, so they are the same.
|
||||
// Just return the value.
|
||||
val
|
||||
converted_val = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
T::from_endian_bytes(val.as_bytes().as_slice(), Endianess::Network)
|
||||
converted_val = try!(T::from_endian_bytes(val.as_bytes().as_slice(),
|
||||
Endianess::Network));
|
||||
}
|
||||
|
||||
Ok(converted_val)
|
||||
}
|
||||
|
||||
/// Turns a Platform order value to a Network order value.
|
||||
pub fn platform_to_network_order<T>(val: T) -> T
|
||||
pub fn platform_to_network_order<T>(val: T) -> Result<T, ConversionError>
|
||||
where T: Transmutable
|
||||
{
|
||||
let converted_val: T;
|
||||
|
||||
// Determine what endianess the Platform is using.
|
||||
if cfg!(target_endian="big")
|
||||
if cfg!(target_endian = "big")
|
||||
{
|
||||
// Network endianess is Big endian, so they are the same.
|
||||
// Just return the value.
|
||||
val
|
||||
converted_val = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
T::from_endian_bytes(val.as_bytes().as_slice(), Endianess::Network)
|
||||
converted_val = try!(T::from_endian_bytes(val.as_bytes().as_slice(),
|
||||
Endianess::Network));
|
||||
}
|
||||
|
||||
Ok(converted_val)
|
||||
}
|
||||
|
||||
/// Returns the Endianess used for network transmission.
|
||||
|
@ -4,7 +4,6 @@
|
||||
#![doc(html_logo_url="",
|
||||
html_favicon_url="http://cybermagesllc.com/favicon.ico",
|
||||
html_root_url="http://cybermagesllc.com")]
|
||||
#![feature(associated_consts)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
|
||||
@ -12,6 +11,9 @@
|
||||
#[macro_use]
|
||||
extern crate scribe;
|
||||
|
||||
extern crate weave;
|
||||
extern crate spellbook;
|
||||
|
||||
#[cfg(feature="sigils")]
|
||||
extern crate sigils;
|
||||
|
||||
@ -21,6 +23,7 @@ extern crate sigils;
|
||||
mod macros;
|
||||
|
||||
mod byte_sized;
|
||||
mod conversion_error;
|
||||
mod converter;
|
||||
mod endian;
|
||||
mod transmutable;
|
||||
@ -32,6 +35,7 @@ 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 ::byte_sized::get_byte_size_of_string;
|
||||
pub use ::conversion_error::ConversionError;
|
||||
pub use ::converter::Converter;
|
||||
pub use ::endian::{BigEndian, LittleEndian, PlatformEndian, NetworkEndian};
|
||||
pub use ::endian::Endianess;
|
||||
|
@ -4,6 +4,46 @@
|
||||
|
||||
|
||||
|
||||
/// Handles the testing of a buffers size and returning the correct
|
||||
/// error if a buffer does not have the correct amount of bytes.
|
||||
macro_rules! check_length
|
||||
{
|
||||
// This tests for the buffers length being less than the min value.
|
||||
// [min_bytes, ∞]
|
||||
($buffer: ident >= $min_bytes: expr) =>
|
||||
{
|
||||
if $buffer.len() < $min_bytes
|
||||
{
|
||||
return Err(::conversion_error::ConversionError::TooFewBytes);
|
||||
}
|
||||
};
|
||||
|
||||
// This tests for the buffers length being more than the max value.
|
||||
// [0, max_value]
|
||||
($buffer: ident <= $max_bytes: expr) =>
|
||||
{
|
||||
if $buffer.len() > $max_bytes
|
||||
{
|
||||
return Err(::conversion_error::ConversionError::TooManyBytes);
|
||||
}
|
||||
};
|
||||
|
||||
// This tests for the buffers length being within the given boundaries.
|
||||
// [min_value, max_value]
|
||||
($buffer: ident, $min_bytes: expr, $max_bytes: expr) =>
|
||||
{
|
||||
check_length!($buffer >= $min_bytes);
|
||||
check_length!($buffer <= $max_bytes);
|
||||
};
|
||||
|
||||
// This tests for the buffers length being equal to the given amount.
|
||||
// [bytes, bytes]
|
||||
($buffer: ident == $bytes: expr) =>
|
||||
{
|
||||
check_length!($buffer, $bytes, $bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles the repetative bit packing for big endian.
|
||||
macro_rules! pack_big_endian
|
||||
{
|
||||
@ -12,11 +52,9 @@ macro_rules! pack_big_endian
|
||||
{
|
||||
let mut value: $target_type;
|
||||
|
||||
// Make sure that there is enough data to read
|
||||
// the bytes for this type.
|
||||
assert!($buffer.len() >= $bytes);
|
||||
check_length!($buffer >= $bytes);
|
||||
|
||||
// Start with a value of zero and or it with
|
||||
// Start with a value of zero and OR it with
|
||||
// the bits shifted values from the buffer.
|
||||
value = 0;
|
||||
for i in 0..$bytes
|
||||
@ -24,8 +62,7 @@ macro_rules! pack_big_endian
|
||||
value |= ($buffer[i] as $target_type) << ((($bytes - i) - 1) * 8);
|
||||
}
|
||||
|
||||
// Return the determined value.
|
||||
value
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,11 +75,9 @@ macro_rules! pack_little_endian
|
||||
{
|
||||
let mut value: $target_type;
|
||||
|
||||
// Make sure that there is enough data to read
|
||||
// the bytes for this type.
|
||||
assert!($buffer.len() >= $bytes);
|
||||
check_length!($buffer >= $bytes);
|
||||
|
||||
// Start with a value of zero and or it with
|
||||
// Start with a value of zero and OR it with
|
||||
// the bits shifted values from the buffer.
|
||||
value = 0;
|
||||
for i in 0..$bytes
|
||||
@ -51,8 +86,7 @@ macro_rules! pack_little_endian
|
||||
((($bytes - i) - 1) * 8);
|
||||
}
|
||||
|
||||
// Return the determined value.
|
||||
value
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,11 +97,11 @@ macro_rules! unpack_big_endian
|
||||
($value: expr, $bytes: expr) =>
|
||||
{
|
||||
{
|
||||
let mut buffer: Vec<u8>;
|
||||
let mut buffer: ::spellbook::components::Array<u8>;
|
||||
|
||||
// Create an array with enough space for this value
|
||||
// and then bit shift the value into a buffer of bytes.
|
||||
buffer = Vec::with_capacity($bytes);
|
||||
buffer = ::spellbook::components::Array::with_capacity($bytes);
|
||||
for i in 0..$bytes
|
||||
{
|
||||
buffer.push(($value >> (($bytes - i) - 1) * 8) as u8);
|
||||
@ -85,11 +119,11 @@ macro_rules! unpack_little_endian
|
||||
($value: expr, $bytes: expr) =>
|
||||
{
|
||||
{
|
||||
let mut buffer: Vec<u8>;
|
||||
let mut buffer: ::spellbook::components::Array<u8>;
|
||||
|
||||
// Create an array with enough space for this value
|
||||
// and then bit shift the value into a buffer of bytes.
|
||||
buffer = Vec::with_capacity($bytes);
|
||||
buffer = ::spellbook::components::Array::with_capacity($bytes);
|
||||
for i in 0..$bytes
|
||||
{
|
||||
buffer.push(($value >> (i * 8)) as u8);
|
||||
@ -107,7 +141,7 @@ macro_rules! swap_big_to_little_endian
|
||||
($value: expr, $target_type: ty, $bytes: expr) =>
|
||||
{
|
||||
{
|
||||
let buffer: Vec<u8>;
|
||||
let buffer: ::spellbook::components::Array<u8>;
|
||||
|
||||
// Convert the big endian value to bytes.
|
||||
buffer = unpack_big_endian!($value, $bytes);
|
||||
@ -124,7 +158,7 @@ macro_rules! swap_little_to_big_endian
|
||||
($value: expr, $target_type: ty, $bytes: expr) =>
|
||||
{
|
||||
{
|
||||
let buffer: Vec<u8>;
|
||||
let buffer: ::spellbook::components::Array<u8>;
|
||||
|
||||
// Convert the little endian value to bytes.
|
||||
buffer = unpack_little_endian!($value, $bytes);
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user