split byte_counter into data_index and rd_counter

fixes #55
This commit is contained in:
Christoph J. Scherr 2024-01-17 15:56:42 +01:00
parent 23910f122e
commit 956e507e39
Signed by: cscherrNT
GPG Key ID: 8E2B45BC51A27EA7
1 changed files with 44 additions and 33 deletions

View File

@ -3,17 +3,18 @@
//! 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.
//! //!
//! This crate is currently empty. //! Hedu is made for hexdumping data. `libpt` offers a cli application using this module.
use crate::display::humanbytes; use crate::display::humanbytes;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use libpt_log::{debug, trace, warn, error}; use libpt_log::{debug, error, trace, warn};
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,
@ -21,6 +22,10 @@ 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 {
@ -32,6 +37,10 @@ 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,
} }
} }
} }
@ -55,14 +64,11 @@ 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)?;
byte_counter += config.skip; config.data_idx += config.skip;
debug!("Skipped {}", humanbytes(config.skip)); debug!("Skipped {}", humanbytes(config.skip));
} }
@ -79,14 +85,14 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
} }
// data dump loop // data dump loop
rd_data(data, &mut buf, &mut alt_buf, &mut byte_counter, &mut config)?; rd_data(data, &mut config)?;
while config.len > 0 { while config.len > 0 {
print!("{:08X} {LINE_SEP_VERT} ", byte_counter); print!("{:08X} {LINE_SEP_VERT} ", config.data_idx);
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} ", buf[alt_buf][i]); print!("{:02X} ", config.buf[config.alt_buf][i]);
} }
if config.len == BYTES_PER_LINE / 2 { if config.len == BYTES_PER_LINE / 2 {
print!(" ") print!(" ")
@ -100,7 +106,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(buf[alt_buf][i] as char)); print!("{}", mask_chars(config.buf[config.alt_buf][i] as char));
} }
print!("|"); print!("|");
} }
@ -112,23 +118,27 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
} }
// after line logic // after line logic
rd_data(data, &mut buf, &mut alt_buf, &mut byte_counter, &mut config)?; rd_data(data, &mut config)?;
alt_buf ^= 1; // toggle the alt buf config.alt_buf ^= 1; // toggle the alt buf
if buf[0] == buf[1] && config.len == BYTES_PER_LINE && !config.show_identical { if config.buf[0] == config.buf[1] && config.len == BYTES_PER_LINE && !config.show_identical
trace!(buf = format!("{:?}", buf), "found a duplicating line"); {
let start_line = byte_counter; trace!(
while buf[0] == buf[1] && config.len == BYTES_PER_LINE { buf = format!("{:?}", config.buf),
rd_data(data, &mut buf, &mut alt_buf, &mut byte_counter, &mut config)?; "found a duplicating line"
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)",
byte_counter - start_line config.data_idx - 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
alt_buf ^= 1; // toggle the alt buf config.alt_buf ^= 1; // toggle the alt buf
} }
Ok(()) Ok(())
} }
@ -147,21 +157,22 @@ fn mask_chars(c: char) -> char {
} }
} }
fn rd_data( fn rd_data(data: &mut dyn DataSource, config: &mut HeduConfig) -> Result<()> {
data: &mut dyn DataSource, config.rd_counter += config.len;
buf: &mut [[u8; BYTES_PER_LINE]; 2], config.data_idx += config.len;
alt_buf: &mut usize, match data.read(&mut config.buf[config.alt_buf]) {
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) => {
if config.limit != 0 && *byte_counter >= config.limit { debug!(
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!(
byte_counter, conf = format!("{:?}", config),
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"
); );