From a125c08032eeea4a46b70e6ca4d5f9cfca593ddb Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Thu, 15 Aug 2024 19:54:34 -0600 Subject: [PATCH] Add ability to parse hex strings --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/formatter/format.rs | 1 + src/formatter/printers.rs | 6 ++++-- src/parser/mod.rs | 25 ++++++++++++++++++++++++- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 061f852..cf45f49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,6 +163,7 @@ version = "0.2.0" dependencies = [ "bitvec", "byteorder", + "hex", "num-bigint", "platform-dirs", "rust-embed", @@ -235,6 +236,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "indexmap" version = "2.2.6" diff --git a/Cargo.toml b/Cargo.toml index 7194fc1..57508c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ byteorder = "1.5.0" num-bigint = "0.4.4" bitvec = "1.0.1" platform-dirs = "0.3.0" +hex = "0.4.3" [dependencies.rust-embed] version = "8.3.0" diff --git a/src/formatter/format.rs b/src/formatter/format.rs index 06ed90e..6a7c380 100644 --- a/src/formatter/format.rs +++ b/src/formatter/format.rs @@ -10,6 +10,7 @@ use crate::byte_stream::{bit_mask, ByteStream, ByteStreamError}; use crate::formatter::printers::PrintType; use crate::FormatConfig; +#[allow(dead_code)] pub trait ByteOrderOperations: ByteOrder { fn last_byte(buf: &mut Vec) -> Option<&mut u8>; diff --git a/src/formatter/printers.rs b/src/formatter/printers.rs index 53d473f..060f648 100644 --- a/src/formatter/printers.rs +++ b/src/formatter/printers.rs @@ -21,7 +21,9 @@ pub fn base_notation(b: u32) -> String { #[derive(Debug, Deserialize, Clone, Default)] #[serde(tag = "print")] pub enum PrintType { - Base { base: u32 }, + Base { + base: u32, + }, ByteArray, String, #[default] @@ -73,7 +75,7 @@ impl PrintType { pub fn print_bytes(&self, bytes: &[u8]) -> String { match self { PrintType::String => std::str::from_utf8(bytes).unwrap().to_string(), - _ => print_bytes_as_array(bytes) + _ => print_bytes_as_array(bytes), } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 614583b..2627fa6 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,3 +1,4 @@ +use hex::FromHexError; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::io::{BufRead, BufReader, Error, Read}; @@ -10,6 +11,7 @@ use std::string::FromUtf8Error; pub enum InputTypes { Array, String, + HexString, Binary, } @@ -22,6 +24,7 @@ impl FromStr for InputTypes { match s.as_str() { "array" | "a" => Ok(Self::Array), "string" | "s" => Ok(Self::String), + "hex_string" | "h" => Ok(Self::HexString), "binary" | "b" => Ok(Self::Binary), _ => Err(format!("Invalid input type '{}'", s)), } @@ -83,6 +86,7 @@ impl InputTypes { let data = match self { InputTypes::Array => Self::parse_array(str_arr, base)?, InputTypes::String => str_arr.join(" ").as_bytes().to_vec(), + InputTypes::HexString => hex::decode(str_arr.join(" "))?, InputTypes::Binary => return Err(ByteArrayParseErr::UnsupportedFormat), }; @@ -114,7 +118,7 @@ impl InputTypes { } match self { - InputTypes::Array | InputTypes::String => { + InputTypes::Array | InputTypes::String | InputTypes::HexString => { let str_data = String::from_utf8(data)?; self.parse_arg_input(vec![str_data], base) } @@ -144,6 +148,7 @@ pub enum ByteArrayParseErr { UnsupportedFormat, FileError(std::io::Error), ParseStringError(FromUtf8Error), + HexDecodeError(hex::FromHexError), } impl From for ByteArrayParseErr { @@ -164,6 +169,12 @@ impl From for ByteArrayParseErr { } } +impl From for ByteArrayParseErr { + fn from(e: FromHexError) -> Self { + Self::HexDecodeError(e) + } +} + impl Display for ByteArrayParseErr { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let err_msg = match self { @@ -174,6 +185,7 @@ impl Display for ByteArrayParseErr { } ByteArrayParseErr::FileError(e) => format!("Unable to parse file: {}", e), ByteArrayParseErr::ParseStringError(e) => format!("Unable to parse string: {}", e), + ByteArrayParseErr::HexDecodeError(e) => format!("Failed to parse hex string: {}", e), }; write!(f, "{}", err_msg) @@ -261,4 +273,15 @@ mod tests { 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); + } }