195 lines
5.0 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|