Add ability to parse hex strings

main
Joey Hines 2024-08-15 19:54:34 -06:00
parent a09cd383e9
commit a125c08032
Signed by: joeyahines
GPG Key ID: 995E531F7A569DDB
5 changed files with 37 additions and 3 deletions

7
Cargo.lock generated
View File

@ -163,6 +163,7 @@ version = "0.2.0"
dependencies = [ dependencies = [
"bitvec", "bitvec",
"byteorder", "byteorder",
"hex",
"num-bigint", "num-bigint",
"platform-dirs", "platform-dirs",
"rust-embed", "rust-embed",
@ -235,6 +236,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.2.6" version = "2.2.6"

View File

@ -13,6 +13,7 @@ byteorder = "1.5.0"
num-bigint = "0.4.4" num-bigint = "0.4.4"
bitvec = "1.0.1" bitvec = "1.0.1"
platform-dirs = "0.3.0" platform-dirs = "0.3.0"
hex = "0.4.3"
[dependencies.rust-embed] [dependencies.rust-embed]
version = "8.3.0" version = "8.3.0"

View File

@ -10,6 +10,7 @@ use crate::byte_stream::{bit_mask, ByteStream, ByteStreamError};
use crate::formatter::printers::PrintType; use crate::formatter::printers::PrintType;
use crate::FormatConfig; use crate::FormatConfig;
#[allow(dead_code)]
pub trait ByteOrderOperations: ByteOrder { pub trait ByteOrderOperations: ByteOrder {
fn last_byte(buf: &mut Vec<u8>) -> Option<&mut u8>; fn last_byte(buf: &mut Vec<u8>) -> Option<&mut u8>;

View File

@ -21,7 +21,9 @@ pub fn base_notation(b: u32) -> String {
#[derive(Debug, Deserialize, Clone, Default)] #[derive(Debug, Deserialize, Clone, Default)]
#[serde(tag = "print")] #[serde(tag = "print")]
pub enum PrintType { pub enum PrintType {
Base { base: u32 }, Base {
base: u32,
},
ByteArray, ByteArray,
String, String,
#[default] #[default]
@ -73,7 +75,7 @@ impl PrintType {
pub fn print_bytes(&self, bytes: &[u8]) -> String { pub fn print_bytes(&self, bytes: &[u8]) -> String {
match self { match self {
PrintType::String => std::str::from_utf8(bytes).unwrap().to_string(), PrintType::String => std::str::from_utf8(bytes).unwrap().to_string(),
_ => print_bytes_as_array(bytes) _ => print_bytes_as_array(bytes),
} }
} }

View File

@ -1,3 +1,4 @@
use hex::FromHexError;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::io::{BufRead, BufReader, Error, Read}; use std::io::{BufRead, BufReader, Error, Read};
@ -10,6 +11,7 @@ use std::string::FromUtf8Error;
pub enum InputTypes { pub enum InputTypes {
Array, Array,
String, String,
HexString,
Binary, Binary,
} }
@ -22,6 +24,7 @@ impl FromStr for InputTypes {
match s.as_str() { match s.as_str() {
"array" | "a" => Ok(Self::Array), "array" | "a" => Ok(Self::Array),
"string" | "s" => Ok(Self::String), "string" | "s" => Ok(Self::String),
"hex_string" | "h" => Ok(Self::HexString),
"binary" | "b" => Ok(Self::Binary), "binary" | "b" => Ok(Self::Binary),
_ => Err(format!("Invalid input type '{}'", s)), _ => Err(format!("Invalid input type '{}'", s)),
} }
@ -83,6 +86,7 @@ impl InputTypes {
let data = match self { let data = match self {
InputTypes::Array => Self::parse_array(str_arr, base)?, InputTypes::Array => Self::parse_array(str_arr, base)?,
InputTypes::String => str_arr.join(" ").as_bytes().to_vec(), InputTypes::String => str_arr.join(" ").as_bytes().to_vec(),
InputTypes::HexString => hex::decode(str_arr.join(" "))?,
InputTypes::Binary => return Err(ByteArrayParseErr::UnsupportedFormat), InputTypes::Binary => return Err(ByteArrayParseErr::UnsupportedFormat),
}; };
@ -114,7 +118,7 @@ impl InputTypes {
} }
match self { match self {
InputTypes::Array | InputTypes::String => { InputTypes::Array | InputTypes::String | InputTypes::HexString => {
let str_data = String::from_utf8(data)?; let str_data = String::from_utf8(data)?;
self.parse_arg_input(vec![str_data], base) self.parse_arg_input(vec![str_data], base)
} }
@ -144,6 +148,7 @@ pub enum ByteArrayParseErr {
UnsupportedFormat, UnsupportedFormat,
FileError(std::io::Error), FileError(std::io::Error),
ParseStringError(FromUtf8Error), ParseStringError(FromUtf8Error),
HexDecodeError(hex::FromHexError),
} }
impl From<ParseIntError> for ByteArrayParseErr { impl From<ParseIntError> for ByteArrayParseErr {
@ -164,6 +169,12 @@ impl From<FromUtf8Error> for ByteArrayParseErr {
} }
} }
impl From<FromHexError> for ByteArrayParseErr {
fn from(e: FromHexError) -> Self {
Self::HexDecodeError(e)
}
}
impl Display for ByteArrayParseErr { impl Display for ByteArrayParseErr {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let err_msg = match self { let err_msg = match self {
@ -174,6 +185,7 @@ impl Display for ByteArrayParseErr {
} }
ByteArrayParseErr::FileError(e) => format!("Unable to parse file: {}", e), ByteArrayParseErr::FileError(e) => format!("Unable to parse file: {}", e),
ByteArrayParseErr::ParseStringError(e) => format!("Unable to parse string: {}", e), ByteArrayParseErr::ParseStringError(e) => format!("Unable to parse string: {}", e),
ByteArrayParseErr::HexDecodeError(e) => format!("Failed to parse hex string: {}", e),
}; };
write!(f, "{}", err_msg) write!(f, "{}", err_msg)
@ -261,4 +273,15 @@ mod tests {
assert_eq!(string.as_bytes(), out) assert_eq!(string.as_bytes(), out)
} }
#[test]
fn parse_hex_string() {
let hex_string = "00112233445566778899aabbccddeeff".to_string();
let out = InputTypes::HexString
.parse_arg_input(vec![hex_string.clone()], None)
.unwrap();
assert_eq!(hex::decode(hex_string).unwrap(), out);
}
} }