Added string and bytes formatting
+ String fields are always null terminated and have a max length + Byte fields are made of raw bytes, and read data until they hit a max length or the end of data is reachedpull/1/head
parent
652682cb19
commit
4e9f4bff1d
|
@ -72,6 +72,10 @@ impl ByteStream {
|
||||||
|
|
||||||
Ok(byte_stream)
|
Ok(byte_stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.data.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&[u8]> for ByteStream {
|
impl From<&[u8]> for ByteStream {
|
||||||
|
|
|
@ -4,11 +4,15 @@ use std::fmt::{Write, Display, Formatter};
|
||||||
use num_bigint::{BigUint, BigInt};
|
use num_bigint::{BigUint, BigInt};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use byteorder::{BigEndian, ReadBytesExt};
|
use byteorder::{BigEndian, ReadBytesExt};
|
||||||
|
use std::string::FromUtf8Error;
|
||||||
|
use crate::formatter::printers::print_bytes_as_array;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum FormatError {
|
pub enum FormatError {
|
||||||
ByteSteamError(ByteStreamError),
|
ByteSteamError(ByteStreamError),
|
||||||
NotSupported
|
#[allow(dead_code)]
|
||||||
|
NotSupported,
|
||||||
|
StringParseError(FromUtf8Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ByteStreamError> for FormatError {
|
impl From<ByteStreamError> for FormatError {
|
||||||
|
@ -17,11 +21,18 @@ impl From<ByteStreamError> for FormatError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<FromUtf8Error> for FormatError {
|
||||||
|
fn from(e: FromUtf8Error) -> Self {
|
||||||
|
FormatError::StringParseError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for FormatError {
|
impl Display for FormatError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
FormatError::ByteSteamError(e) => writeln!(f, "Byte steam error: {}", e),
|
FormatError::ByteSteamError(e) => writeln!(f, "Byte steam error: {}", e),
|
||||||
FormatError::NotSupported => write!(f, "Field type not supported")
|
FormatError::NotSupported => write!(f, "Field type not supported"),
|
||||||
|
FormatError::StringParseError(e) => write!(f, "String parse error: {}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,13 +105,47 @@ impl Field {
|
||||||
Ok((cursor.read_f64::<BigEndian>().unwrap().to_string(), 4))
|
Ok((cursor.read_f64::<BigEndian>().unwrap().to_string(), 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn format_string(byte_stream: &ByteStream, mut bit_ndx: usize, max_byte_len: usize) -> Result<(String, usize), FormatError> {
|
||||||
|
let mut string_bytes = Vec::new();
|
||||||
|
|
||||||
|
for _ in 0..max_byte_len {
|
||||||
|
let byte = byte_stream.get_bytes(bit_ndx, 8)?[0];
|
||||||
|
|
||||||
|
if byte == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_bytes.push(byte);
|
||||||
|
bit_ndx += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
let byte_count = string_bytes.len();
|
||||||
|
Ok((String::from_utf8(string_bytes)?, byte_count))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_bytes(byte_stream: &ByteStream, bit_ndx: usize, max_byte_len: usize) -> Result<(String, usize), FormatError> {
|
||||||
|
let data_remaining = byte_stream.len() - bit_ndx/8;
|
||||||
|
|
||||||
|
let width = if max_byte_len < data_remaining {
|
||||||
|
max_byte_len*8
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data_remaining*8
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = byte_stream.get_bytes(bit_ndx, width)?;
|
||||||
|
|
||||||
|
Ok((print_bytes_as_array(&data), width))
|
||||||
|
}
|
||||||
|
|
||||||
fn format_data(&self, byte_stream: &ByteStream, bit_ndx: usize) -> Result<(String, usize), FormatError> {
|
fn format_data(&self, byte_stream: &ByteStream, bit_ndx: usize) -> Result<(String, usize), FormatError> {
|
||||||
match self.field_type {
|
match self.field_type {
|
||||||
FieldType::UInt { bit_width } => Self::format_uint(byte_stream, bit_ndx, bit_width),
|
FieldType::UInt { bit_width } => Self::format_uint(byte_stream, bit_ndx, bit_width),
|
||||||
FieldType::Int { bit_width } => Self::format_int(byte_stream, bit_ndx, bit_width),
|
FieldType::Int { bit_width } => Self::format_int(byte_stream, bit_ndx, bit_width),
|
||||||
FieldType::Float => Self::format_float(byte_stream, bit_ndx),
|
FieldType::Float => Self::format_float(byte_stream, bit_ndx),
|
||||||
FieldType::Double => Self::format_double(byte_stream, bit_ndx),
|
FieldType::Double => Self::format_double(byte_stream, bit_ndx),
|
||||||
_ => Err(FormatError::NotSupported),
|
FieldType::String {max_len} => Self::format_string(byte_stream, bit_ndx, max_len),
|
||||||
|
FieldType::Bytes {max_len} => Self::format_bytes(byte_stream, bit_ndx, max_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,4 +256,26 @@ mod tests {
|
||||||
|
|
||||||
assert!(field.format_data(&byte_steam, 0).is_err())
|
assert!(field.format_data(&byte_steam, 0).is_err())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_format_string() {
|
||||||
|
let field = Field {field_type: FieldType::String {max_len: 16}, name: "test".to_string()};
|
||||||
|
|
||||||
|
let byte_steam = ByteStream::from(b"Hello World!\0".to_vec());
|
||||||
|
|
||||||
|
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(output, "Hello World!".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_format_bytes() {
|
||||||
|
let field = Field {field_type: FieldType::Bytes {max_len: 2}, name: "test".to_string()};
|
||||||
|
|
||||||
|
let byte_steam = ByteStream::from(vec![0xDE, 0xAD, 0xBE, 0xEF]);
|
||||||
|
|
||||||
|
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(output, "[222, 173]")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod format;
|
pub mod format;
|
||||||
|
mod printers;
|
||||||
|
|
||||||
use crate::formatter::format::Format;
|
use crate::formatter::format::Format;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
|
pub fn print_bytes_as_array(data: &[u8]) -> String {
|
||||||
|
format!("{:?}", data)
|
||||||
|
}
|
Loading…
Reference in New Issue