Skip to content

Commit

Permalink
Merge pull request #10 from matcap/master
Browse files Browse the repository at this point in the history
Address prefix optional offset and variable width support
  • Loading branch information
wolandr authored Jul 23, 2023
2 parents 9ef5b54 + 4d79020 commit 4a889b6
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
26 changes: 25 additions & 1 deletion src/pretty_hex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ pub struct HexConfig {
pub chunk: usize,
/// Maximum bytes to print.
pub max_bytes: usize,
/// Offset added to displayed address prefix
pub display_offset: usize,
}

/// Default configuration with `title`, `ascii`, 16 source bytes `width` grouped to 4 separate
Expand All @@ -75,6 +77,7 @@ impl Default for HexConfig {
group: 4,
chunk: 1,
max_bytes: usize::MAX,
display_offset: 0,
}
}
}
Expand Down Expand Up @@ -109,6 +112,18 @@ impl HexConfig {

const NON_ASCII: char = '.';


type AddressWriter = dyn Fn(&mut dyn fmt::Write, usize) -> fmt::Result;

fn get_address_writer(max_addr: usize) -> &'static AddressWriter{
match max_addr {
0x0000..=0xffff => &|w: &mut dyn fmt::Write, a| write!(w, "{:04x}: ", a),
0x010000..=0xffffff => &|w: &mut dyn fmt::Write, a| write!(w, "{:06x}: ", a),
0x01000000..=0xffffffff => &|w: &mut dyn fmt::Write, a| write!(w, "{:08x}: ", a),
_ => &|w: &mut dyn fmt::Write, a| write!(w, "{:016x}: ", a)
}
}

/// Write hex dump in specified format.
pub fn hex_write<T, W>(writer: &mut W, source: &T, cfg: HexConfig) -> fmt::Result
where
Expand All @@ -133,10 +148,19 @@ where
} else {
source.len()
});

let lines_len = lines.len();

let max_address = if source.len() <= cfg.width {
source.len() + cfg.display_offset
} else {
source.len() - cfg.width + cfg.display_offset
};
let write_address = get_address_writer(max_address);

for (i, row) in lines.enumerate() {
if cfg.width > 0 {
write!(writer, "{:04x}: ", i * cfg.width)?;
write_address(writer, i * cfg.width + cfg.display_offset)?;
}
for (i, x) in row.as_ref().iter().enumerate() {
write!(writer, "{}{:02x}", cfg.delimiter(i), x)?;
Expand Down
15 changes: 15 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ fn test_config() {
group: 0,
chunk: 0,
max_bytes: usize::MAX,
display_offset: 0
};
assert!(config_hex(&vec![], cfg).is_empty());
assert_eq!("2425262728", config_hex(&"$%&'(", cfg));
Expand Down Expand Up @@ -95,6 +96,18 @@ fn test_config() {
0010: 89d5 cf90 2367 4b48 dbb1 bc35 bfee"
);

assert_eq!(
config_hex(&v,
HexConfig {
ascii: false,
display_offset: 0x200,
..cfg
}
),
"0200: 6b 4e 1a c3 af 03 d2 1e 7e 73 ba c8 bd 84 0f 83\n\
0210: 89 d5 cf 90 23 67 4b 48 db b1 bc 35 bf ee"
);

let v: Vec<u8> = (0..21).collect();
let want = r##"Length: 21 (0x15) bytes
0000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
Expand All @@ -111,6 +124,7 @@ fn test_config() {
group: 2,
chunk: 3,
max_bytes: usize::MAX,
display_offset: 0
}),
"0000: 000102 030405 060708 090a ...........\n\
000b: 0b0c .."
Expand All @@ -126,6 +140,7 @@ fn test_config() {
group: 3,
chunk: 3,
max_bytes: usize::MAX,
display_offset: 0
}
),
"0000: 000102 030405 060708 090a0b 0c0d0e 0f ................\n\
Expand Down

0 comments on commit 4a889b6

Please sign in to comment.