use crate::bits::{Error, MutBits};
use alloc::vec::Vec;
pub static HEX_UPPER_CHARS: [char; 16] = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
];
pub static HEX_LOWER_CHARS: [char; 16] = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
];
pub trait HexDump {
#[cfg(feature = "std")]
fn hexdump(&self);
fn hexdump_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<(), Error>;
}
impl<S: AsRef<[u8]>> HexDump for S {
#[cfg(feature = "std")]
fn hexdump(&self) {
let _ = self.hexdump_to(&mut crate::bits::BitsWrapper(&mut std::io::stdout().lock()));
}
fn hexdump_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<(), Error> {
let mut idx = 0;
let val = self.as_ref();
loop {
write!(out, "{idx:08X} ")?;
let mut buf = Vec::new();
for sidx in 0..16 {
let Some(v) = val.get(idx + sidx) else {
break;
};
buf.push(*v);
}
for v in &buf {
write!(out, "{v:02X} ")?;
}
for _i in 0..(16 - buf.len()) {
write!(out, " ")?;
}
write!(out, " |")?;
for v in &buf {
match *v {
0..=0x1F | 0x7F..=0xA0 | 0xFF => {
write!(out, ".")?;
}
p => {
write!(out, "{}", p as char)?;
}
}
}
for _i in 0..(16 - buf.len()) {
write!(out, " ")?;
}
writeln!(out, "|")?;
idx += 16;
if buf.len() != 16 {
break;
}
}
Ok(())
}
}
#[cfg(test)]
#[cfg(feature = "std")]
mod tests {
use crate::hex::HexDump;
use alloc::vec::Vec;
#[test]
pub fn test() -> Result<(), crate::bits::Error> {
let mut buf: Vec<u8> = Vec::new();
for v in u8::MIN..=u8::MAX {
buf.push(v);
}
buf.hexdump();
Ok(())
}
}