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:
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.
|
||||
|
Reference in New Issue
Block a user