//! Hex + ASCII rendering, shared by `read` and by `find`'s context blocks. use std::fmt::Write as _; use std::io::{self, Write}; fn ascii_gutter(row: &[u8]) -> String { row.iter() .map(|&b| { if (0x20..=0x7e).contains(&b) { b as char } else { '.' } }) .collect() } /// Classic 16-bytes-per-line dump with absolute addresses in the left column. pub fn hexdump(out: &mut impl Write, base: u64, data: &[u8], indent: &str) -> io::Result<()> { for (i, row) in data.chunks(16).enumerate() { let addr = base + (i * 16) as u64; let mut hex = String::with_capacity(50); for (j, b) in row.iter().enumerate() { if j == 8 { hex.push(' '); } // Writing into a String is infallible. let _ = write!(hex, "{b:02x} "); } writeln!(out, "{indent}{addr:012x} {hex:<50}|{}|", ascii_gutter(row))?; } Ok(()) }