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:
2018-01-05 19:20:02 -05:00
parent 3a1b847c51
commit ff3558ea37
12 changed files with 505 additions and 396 deletions

View File

@ -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.