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"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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]]
|
[[package]]
|
||||||
name = "sigils"
|
name = "sigils"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2,6 +2,15 @@
|
|||||||
name = "alchemy"
|
name = "alchemy"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Jason Travis Smith <Jason@CyberMagesLLC.com>"]
|
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]
|
[dependencies.sigils]
|
||||||
git = "https://gitlab.com/CyberMages/sigils.git"
|
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!((i32, I32_BYTES) (i64, U64_BYTES));
|
||||||
byte_sized_impl!((f32, F32_BYTES) (f64, F64_BYTES));
|
byte_sized_impl!((f32, F32_BYTES) (f64, F64_BYTES));
|
||||||
byte_sized_impl!((usize, USIZE_BYTES) (isize, ISIZE_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
|
/// 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);
|
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.
|
/// and writing them to a buffer.
|
||||||
macro_rules! write_bytes
|
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,
|
assert!($buffer.len() >= $valueType::BYTES,
|
||||||
"Not enough room in the buffer to write to.");
|
"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);
|
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
|
impl Converter for LittleEndian
|
||||||
@ -234,6 +296,67 @@ impl Converter for LittleEndian
|
|||||||
num_bytes as usize);
|
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.
|
//! The Alchemy library is a data type to byte converter library.
|
||||||
//! Alchemy handles converting numbers to and from bytes
|
//! Alchemy handles converting numbers to and from bytes
|
||||||
//! in either big or little endian format.
|
//! 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)]
|
#![feature(associated_consts)]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate scribe;
|
||||||
|
|
||||||
extern crate sigils;
|
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::{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::{I8_BYTES, I16_BYTES, I32_BYTES, I64_BYTES, ISIZE_BYTES};
|
||||||
pub use ::byte_sized::{F32_BYTES, F64_BYTES};
|
pub use ::byte_sized::{F32_BYTES, F64_BYTES};
|
||||||
|
pub use ::byte_sized::get_byte_size_of_string;
|
||||||
pub use ::converter::Converter;
|
pub use ::converter::Converter;
|
||||||
pub use ::endian::{BigEndian, LittleEndian, PlatformEndian, Endianess};
|
pub use ::endian::{BigEndian, LittleEndian, PlatformEndian, Endianess};
|
||||||
pub use ::transmutable::Transmutable;
|
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
|
impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable
|
||||||
{
|
{
|
||||||
fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess)
|
fn to_bytes(&self, buffer: &mut [u8], endianess: Endianess)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user