hd/hdinfo.rs
2024-01-10 01:09:15 -06:00

195 lines
5.0 KiB
Rust

// Contain information for hexdump
const BUFFERSIZE:usize=4096;
pub struct Hdinfo
{
pub columns:usize,
pub showoffset:bool,
pub showascii:bool,
pub numbytes:usize,
pub radix:u32,
pub percent:f32,
pub offset:usize,
}
impl Hdinfo
{
// Initialize Hdinfo struct
pub fn new()->Hdinfo
{
return Hdinfo{
columns:16,
showoffset:true,
showascii:true,
numbytes:0,
radix:16,
percent:1.0,
offset:0,
}
}
// Hexdump a buffer
pub fn hexdump_buffer(&mut self,buffer:&Vec<u8>,mut length:usize)
{
let mut i:usize=0;
// Set length appropriately
if self.numbytes>0 && self.numbytes<length
{
length=self.numbytes;
}
else if self.percent<1.0
{
length=(buffer.len() as f32*self.percent) as usize;
}
while i<length
{
let left=self.columns as i32-(length as i32-i as i32);
if self.showoffset
{
print!("{:08X}: ",self.offset+i);
}
// Hexdump
for j in 0..self.columns
{
if i+j>=length {break;}
if self.radix==2
{
print!("{:08b} ",buffer[i+j] as u32);
}
else if self.radix==8
{
print!("{:03o} ",buffer[i+j] as u32);
}
else if self.radix==10
{
print!("{:>3} ",buffer[i+j] as u32);
}
else if self.radix==16
{
print!("{:02X} ",buffer[i+j] as u32);
}
else
{
print!("error: unrecognized radix '{}'\n",self.radix);
std::process::exit(1);
}
}
if self.showascii
{
// ASCII
for _ in 0..left
{
if self.radix==16
{
print!(" ");
}
else if self.radix==2
{
print!(" ");
}
else //if self.radix==8
{
print!(" ");
}
}
for j in 0..self.columns
{
if i+j>=length {break;}
if (buffer[i+j] as u32 > 32) && (buffer[i+j] as u32) < 127
{
print!("{}",buffer[i+j] as char);
}
else
{
print!(".");
}
}
}
print!("\n");
i+=self.columns;
}
self.offset+=length;
}
pub fn hexdump_filenames_or_stdin(&mut self,filenames:&Vec<String>)
{
// Round up to nearest multiple of self.columns
let buffersize:usize=(BUFFERSIZE+self.columns)-(BUFFERSIZE%self.columns);
// Hexdump each argument previously
// identified as a filename
if filenames.len()==0
{
let mut buffer:Vec<u8>=vec![0;buffersize];
let mut file=std::io::stdin().lock();
// Hexdump input
loop
{
let n_read=match std::io::Read::read(&mut file,&mut buffer)
{
Ok(n)=>n,
Err(e)=>{
print!("error: {}\n",e);
std::process::exit(1);
}
};
if n_read==0
{
break;
}
self.hexdump_buffer(&buffer,n_read);
}
}
else
{
for filename in filenames
{
if filenames.len()>1usize
{
print!("{}:\n",filename);
}
let mut buffer:Vec<u8>=vec![0;buffersize];
let mut file=match std::fs::File::open(filename)
{
Ok(ff)=>ff,
Err(e)=>{
print!("error: {}\n",e);
std::process::exit(1);
}
};
// Hexdump file
loop
{
let n_read=match std::io::Read::read(&mut file,&mut buffer)
{
Ok(n)=>n,
Err(e)=>{
print!("error: {}\n",e);
std::process::exit(1);
}
};
if n_read==0
{
break;
}
self.hexdump_buffer(&buffer,n_read);
}
}
}
}
}