generated from PlexSheep/baserepo
Compare commits
No commits in common. "b3013caacc920411e84e197c05e4b2eab3ee7b1a" and "1afaf6d3d2c51d00fd1a002efec697c230679713" have entirely different histories.
b3013caacc
...
1afaf6d3d2
1 changed files with 33 additions and 44 deletions
|
@ -3,18 +3,17 @@
|
||||||
//! This crate is part of [`pt`](../libpt/index.html), but can also be used as a standalone
|
//! This crate is part of [`pt`](../libpt/index.html), but can also be used as a standalone
|
||||||
//! module.
|
//! module.
|
||||||
//!
|
//!
|
||||||
//! Hedu is made for hexdumping data. `libpt` offers a cli application using this module.
|
//! This crate is currently empty.
|
||||||
|
|
||||||
use crate::display::humanbytes;
|
use crate::display::humanbytes;
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use libpt_log::{debug, error, trace, warn};
|
use libpt_log::{debug, trace, warn, error};
|
||||||
use std::io::{prelude::*, Read, SeekFrom};
|
use std::io::{prelude::*, Read, SeekFrom};
|
||||||
|
|
||||||
const BYTES_PER_LINE: usize = 16;
|
const BYTES_PER_LINE: usize = 16;
|
||||||
const LINE_SEP_HORIZ: char = '─';
|
const LINE_SEP_HORIZ: char = '─';
|
||||||
const LINE_SEP_VERT: char = '│';
|
const LINE_SEP_VERT: char = '│';
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct HeduConfig {
|
pub struct HeduConfig {
|
||||||
pub chars: bool,
|
pub chars: bool,
|
||||||
pub skip: usize,
|
pub skip: usize,
|
||||||
|
@ -22,10 +21,6 @@ pub struct HeduConfig {
|
||||||
pub limit: usize,
|
pub limit: usize,
|
||||||
stop: bool,
|
stop: bool,
|
||||||
len: usize,
|
len: usize,
|
||||||
data_idx: usize,
|
|
||||||
rd_counter: usize,
|
|
||||||
buf: [[u8; BYTES_PER_LINE]; 2],
|
|
||||||
alt_buf: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeduConfig {
|
impl HeduConfig {
|
||||||
|
@ -37,10 +32,6 @@ impl HeduConfig {
|
||||||
limit,
|
limit,
|
||||||
stop: false,
|
stop: false,
|
||||||
len: usize::MIN,
|
len: usize::MIN,
|
||||||
data_idx: usize::MIN,
|
|
||||||
rd_counter: usize::MIN,
|
|
||||||
buf: [[0; BYTES_PER_LINE]; 2],
|
|
||||||
alt_buf: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,11 +55,14 @@ impl DataSource for std::fs::File {
|
||||||
|
|
||||||
pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
||||||
// prepare some variables
|
// prepare some variables
|
||||||
|
let mut buf: [[u8; BYTES_PER_LINE]; 2] = [[0; BYTES_PER_LINE]; 2];
|
||||||
|
let mut alt_buf = 0usize;
|
||||||
|
let mut byte_counter: usize = 0;
|
||||||
|
|
||||||
// skip a given number of bytes
|
// skip a given number of bytes
|
||||||
if config.skip > 0 {
|
if config.skip > 0 {
|
||||||
data.skip(config.skip)?;
|
data.skip(config.skip)?;
|
||||||
config.data_idx += config.skip;
|
byte_counter += config.skip;
|
||||||
debug!("Skipped {}", humanbytes(config.skip));
|
debug!("Skipped {}", humanbytes(config.skip));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,14 +79,14 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// data dump loop
|
// data dump loop
|
||||||
rd_data(data, &mut config)?;
|
rd_data(data, &mut buf, &mut alt_buf, &mut byte_counter, &mut config)?;
|
||||||
while config.len > 0 {
|
while config.len > 0 {
|
||||||
print!("{:08X} {LINE_SEP_VERT} ", config.data_idx);
|
print!("{:08X} {LINE_SEP_VERT} ", byte_counter);
|
||||||
for i in 0..config.len {
|
for i in 0..config.len {
|
||||||
if i as usize % BYTES_PER_LINE == BYTES_PER_LINE / 2 {
|
if i as usize % BYTES_PER_LINE == BYTES_PER_LINE / 2 {
|
||||||
print!(" ");
|
print!(" ");
|
||||||
}
|
}
|
||||||
print!("{:02X} ", config.buf[config.alt_buf][i]);
|
print!("{:02X} ", buf[alt_buf][i]);
|
||||||
}
|
}
|
||||||
if config.len == BYTES_PER_LINE / 2 {
|
if config.len == BYTES_PER_LINE / 2 {
|
||||||
print!(" ")
|
print!(" ")
|
||||||
|
@ -106,7 +100,7 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
||||||
if config.chars {
|
if config.chars {
|
||||||
print!("{LINE_SEP_VERT} |");
|
print!("{LINE_SEP_VERT} |");
|
||||||
for i in 0..config.len {
|
for i in 0..config.len {
|
||||||
print!("{}", mask_chars(config.buf[config.alt_buf][i] as char));
|
print!("{}", mask_chars(buf[alt_buf][i] as char));
|
||||||
}
|
}
|
||||||
print!("|");
|
print!("|");
|
||||||
}
|
}
|
||||||
|
@ -118,27 +112,23 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// after line logic
|
// after line logic
|
||||||
rd_data(data, &mut config)?;
|
rd_data(data, &mut buf, &mut alt_buf, &mut byte_counter, &mut config)?;
|
||||||
config.alt_buf ^= 1; // toggle the alt buf
|
alt_buf ^= 1; // toggle the alt buf
|
||||||
if config.buf[0] == config.buf[1] && config.len == BYTES_PER_LINE && !config.show_identical
|
if buf[0] == buf[1] && config.len == BYTES_PER_LINE && !config.show_identical {
|
||||||
{
|
trace!(buf = format!("{:?}", buf), "found a duplicating line");
|
||||||
trace!(
|
let start_line = byte_counter;
|
||||||
buf = format!("{:?}", config.buf),
|
while buf[0] == buf[1] && config.len == BYTES_PER_LINE {
|
||||||
"found a duplicating line"
|
rd_data(data, &mut buf, &mut alt_buf, &mut byte_counter, &mut config)?;
|
||||||
);
|
byte_counter += BYTES_PER_LINE;
|
||||||
let start_line = config.data_idx;
|
|
||||||
while config.buf[0] == config.buf[1] && config.len == BYTES_PER_LINE {
|
|
||||||
rd_data(data, &mut config)?;
|
|
||||||
config.data_idx += BYTES_PER_LINE;
|
|
||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
"^^^^^^^^ {LINE_SEP_VERT} (repeats {} lines)",
|
"^^^^^^^^ {LINE_SEP_VERT} (repeats {} lines)",
|
||||||
config.data_idx - start_line
|
byte_counter - start_line
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// switch to the second half of the buf, the original half is stored the old buffer
|
// switch to the second half of the buf, the original half is stored the old buffer
|
||||||
// We detect duplicate lines with this
|
// We detect duplicate lines with this
|
||||||
config.alt_buf ^= 1; // toggle the alt buf
|
alt_buf ^= 1; // toggle the alt buf
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -157,22 +147,21 @@ fn mask_chars(c: char) -> char {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rd_data(data: &mut dyn DataSource, config: &mut HeduConfig) -> Result<()> {
|
fn rd_data(
|
||||||
config.rd_counter += config.len;
|
data: &mut dyn DataSource,
|
||||||
config.data_idx += config.len;
|
buf: &mut [[u8; BYTES_PER_LINE]; 2],
|
||||||
match data.read(&mut config.buf[config.alt_buf]) {
|
alt_buf: &mut usize,
|
||||||
|
byte_counter: &mut usize,
|
||||||
|
config: &mut HeduConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
*byte_counter += config.len;
|
||||||
|
match data.read(&mut buf[*alt_buf]) {
|
||||||
Ok(mut len) => {
|
Ok(mut len) => {
|
||||||
debug!(
|
if config.limit != 0 && *byte_counter >= config.limit {
|
||||||
conf = format!("{:?}", config),
|
|
||||||
dif = (config.rd_counter as i64 - config.skip as i64),
|
|
||||||
eval = (config.rd_counter as i64 - config.skip as i64) as usize >= config.limit,
|
|
||||||
"reached limit?"
|
|
||||||
);
|
|
||||||
if config.limit != 0
|
|
||||||
&& (config.rd_counter as i64 - config.skip as i64) as usize >= config.limit
|
|
||||||
{
|
|
||||||
trace!(
|
trace!(
|
||||||
conf = format!("{:?}", config),
|
byte_counter,
|
||||||
|
limit = config.limit,
|
||||||
|
len,
|
||||||
nlen = (config.limit % BYTES_PER_LINE),
|
nlen = (config.limit % BYTES_PER_LINE),
|
||||||
"byte counter is farther than limit"
|
"byte counter is farther than limit"
|
||||||
);
|
);
|
||||||
|
|
Reference in a new issue