Strings can now be transmuted or converted into binary data.
This also added the scribe library so that this library can use the logging system.
This commit is contained in:
parent
d1c4b3e053
commit
e9ab0bdece
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -3,6 +3,7 @@ name = "alchemy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scribe 0.1.0 (git+https://gitlab.com/CyberMages/scribe.git)",
|
||||
"sigils 0.1.0 (git+https://gitlab.com/CyberMages/sigils.git)",
|
||||
]
|
||||
|
||||
@ -30,6 +31,11 @@ dependencies = [
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scribe"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitlab.com/CyberMages/scribe.git#e52418d3bfc28cd1f03cc7f31af06fce2e03f844"
|
||||
|
||||
[[package]]
|
||||
name = "sigils"
|
||||
version = "0.1.0"
|
||||
|
@ -2,6 +2,15 @@
|
||||
name = "alchemy"
|
||||
version = "0.1.0"
|
||||
authors = ["Jason Travis Smith <Jason@CyberMagesLLC.com>"]
|
||||
description = "Handles converting values to and from a binary format."
|
||||
license = ""
|
||||
repository = "https://gitlab.com/CyberMages/alchemy.git"
|
||||
documentation = ""
|
||||
keywords = ["converter", "binary"]
|
||||
|
||||
|
||||
[dependencies.scribe]
|
||||
git = "https://gitlab.com/CyberMages/scribe.git"
|
||||
|
||||
[dependencies.sigils]
|
||||
git = "https://gitlab.com/CyberMages/sigils.git"
|
||||
|
@ -115,3 +115,20 @@ byte_sized_impl!((i8, I8_BYTES) (i16, I16_BYTES));
|
||||
byte_sized_impl!((i32, I32_BYTES) (i64, U64_BYTES));
|
||||
byte_sized_impl!((f32, F32_BYTES) (f64, F64_BYTES));
|
||||
byte_sized_impl!((usize, USIZE_BYTES) (isize, ISIZE_BYTES));
|
||||
|
||||
|
||||
/// This returns the amount of bytes it takes to store a string
|
||||
/// in a binary format. This includes the u64 size we prepend to
|
||||
/// store the amount of bytes of data in the String.
|
||||
pub fn get_byte_size_of_string(string: &String) -> usize
|
||||
{
|
||||
let bytes: &[u8];
|
||||
|
||||
// Turn the string into a byte array.
|
||||
bytes = string.as_bytes();
|
||||
|
||||
// Determine how many bytes will be written
|
||||
// for this string and add the amount of
|
||||
// bytes needed for the u64 size.
|
||||
bytes.len() + U64_BYTES
|
||||
}
|
||||
|
@ -231,6 +231,26 @@ pub trait Converter
|
||||
/// passed in is less than the byte size of the given number
|
||||
/// or more than eight.
|
||||
fn usize_to_bytes(buffer: &mut [u8], num: usize);
|
||||
|
||||
|
||||
/// Converts a String to bytes
|
||||
/// and places them into the given buffer.
|
||||
///
|
||||
/// # Panics
|
||||
/// This will panic if the buffer does not have
|
||||
/// enough space to store the converted value.
|
||||
///
|
||||
/// 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;
|
||||
|
||||
/// 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(buffer: &mut [u8], string: String);
|
||||
}
|
||||
|
||||
|
||||
|
125
src/endian.rs
125
src/endian.rs
@ -74,7 +74,8 @@ macro_rules! read_bytes
|
||||
/// and writing them to a buffer.
|
||||
macro_rules! write_bytes
|
||||
{
|
||||
($buffer: expr, $valueType: ident, $numBytes: expr, $num: expr, $convertFunc: ident) =>
|
||||
($buffer: expr, $valueType: ident, $numBytes: expr,
|
||||
$num: expr, $convertFunc: ident) =>
|
||||
({
|
||||
assert!($buffer.len() >= $valueType::BYTES,
|
||||
"Not enough room in the buffer to write to.");
|
||||
@ -166,6 +167,67 @@ impl Converter for BigEndian
|
||||
buffer.as_mut_ptr(), num_bytes as usize);
|
||||
}
|
||||
}
|
||||
|
||||
fn bytes_to_string(buffer: &[u8]) -> String
|
||||
{
|
||||
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);
|
||||
|
||||
if byte_count > 0
|
||||
{
|
||||
match String::from_utf8(buffer[U64_BYTES..(buffer.len()-1)].to_vec())
|
||||
{
|
||||
Ok(string) =>
|
||||
{
|
||||
new_string = string;
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
error!("{}", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_string = String::new();
|
||||
}
|
||||
|
||||
new_string
|
||||
}
|
||||
|
||||
fn string_to_bytes(buffer: &mut [u8], string: String)
|
||||
{
|
||||
let bytes: &[u8];
|
||||
let byte_count: u64;
|
||||
|
||||
// Turn the string into a byte array.
|
||||
bytes = string.as_bytes();
|
||||
|
||||
// Determine how many bytes will be written
|
||||
// for this string.
|
||||
byte_count = bytes.len() as u64;
|
||||
|
||||
// Make sure the buffer has enough space for this string.
|
||||
assert!(buffer.len() as u64 >= byte_count + U64_BYTES as u64);
|
||||
|
||||
// Add the count to the buffer.
|
||||
BigEndian::u64_to_bytes(&mut buffer[0..U64_BYTES], byte_count);
|
||||
|
||||
// Add each byte of the string to the buffer.
|
||||
for (i, byte) in bytes.iter().enumerate()
|
||||
{
|
||||
buffer[U64_BYTES + i] = byte.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Converter for LittleEndian
|
||||
@ -234,6 +296,67 @@ impl Converter for LittleEndian
|
||||
num_bytes as usize);
|
||||
}
|
||||
}
|
||||
|
||||
fn bytes_to_string(buffer: &[u8]) -> String
|
||||
{
|
||||
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);
|
||||
|
||||
if byte_count > 0
|
||||
{
|
||||
match String::from_utf8(buffer[U64_BYTES..(buffer.len()-1)].to_vec())
|
||||
{
|
||||
Ok(string) =>
|
||||
{
|
||||
new_string = string;
|
||||
}
|
||||
|
||||
Err(error) =>
|
||||
{
|
||||
error!("{}", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_string = String::new();
|
||||
}
|
||||
|
||||
new_string
|
||||
}
|
||||
|
||||
fn string_to_bytes(buffer: &mut [u8], string: String)
|
||||
{
|
||||
let bytes: &[u8];
|
||||
let byte_count: u64;
|
||||
|
||||
// Turn the string into a byte array.
|
||||
bytes = string.as_bytes();
|
||||
|
||||
// Determine how many bytes will be written
|
||||
// for this string.
|
||||
byte_count = bytes.len() as u64 + U64_BYTES as u64;
|
||||
|
||||
// Make sure the buffer has enough space for this string.
|
||||
assert!(buffer.len() as u64 >= byte_count);
|
||||
|
||||
// Add the count to the buffer.
|
||||
LittleEndian::u64_to_bytes(&mut buffer[0..U64_BYTES], byte_count);
|
||||
|
||||
// Add each byte of the string to the buffer.
|
||||
for (i, byte) in bytes.iter().enumerate()
|
||||
{
|
||||
buffer[U64_BYTES + i] = byte.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,9 +1,15 @@
|
||||
//! The Alchemy library is a data type to byte converter library.
|
||||
//! Alchemy handles converting numbers to and from bytes
|
||||
//! in either big or little endian format.
|
||||
#![doc(html_logo_url="http://cybermagesllc.com/wp-content/uploads/2012/06/logo-300x300.png",
|
||||
html_favicon_url="http://cybermagesllc.com/favicon.ico",
|
||||
html_root_url="http://cybermagesllc.com")]
|
||||
#![feature(associated_consts)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate scribe;
|
||||
|
||||
extern crate sigils;
|
||||
|
||||
|
||||
@ -19,6 +25,7 @@ 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 ::byte_sized::get_byte_size_of_string;
|
||||
pub use ::converter::Converter;
|
||||
pub use ::endian::{BigEndian, LittleEndian, PlatformEndian, Endianess};
|
||||
pub use ::transmutable::Transmutable;
|
||||
|
@ -366,6 +366,48 @@ impl Transmutable for f64
|
||||
}
|
||||
}
|
||||
|
||||
impl Transmutable for String
|
||||
{
|
||||
fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess)
|
||||
{
|
||||
let temp: String;
|
||||
let mut mut_buffer;
|
||||
|
||||
// Create a mutable handle to the buffer.
|
||||
mut_buffer = buffer;
|
||||
|
||||
// Clone the string so that we can use its data.
|
||||
// We have to do this because Strings don't implement Copy.
|
||||
temp = self.clone();
|
||||
|
||||
// Convert this to bytes and add it to the buffer.
|
||||
// We are not using the macro because *String is a str.
|
||||
match endianess
|
||||
{
|
||||
Endianess::BIG =>
|
||||
{
|
||||
BigEndian::string_to_bytes(&mut mut_buffer, temp);
|
||||
}
|
||||
|
||||
Endianess::LITTLE =>
|
||||
{
|
||||
LittleEndian::string_to_bytes(&mut mut_buffer, temp);
|
||||
}
|
||||
|
||||
Endianess::PLATFORM =>
|
||||
{
|
||||
PlatformEndian::string_to_bytes(&mut mut_buffer, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_bytes(buffer: &[u8], endianess: Endianess) -> String
|
||||
{
|
||||
// Convert the given bytes to this type and return it.
|
||||
handle_endianess_from_bytes!(buffer, endianess, bytes_to_string)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable
|
||||
{
|
||||
fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess)
|
||||
|
Loading…
x
Reference in New Issue
Block a user