read from multiple sources
cargo devel CI / cargo CI (push) Successful in 2m6s Details

implements #60
This commit is contained in:
Christoph J. Scherr 2024-01-17 23:02:41 +01:00
parent fd0d1e3c22
commit 2bc75970a4
Signed by: PlexSheep
GPG Key ID: 7CDD0B14851A08EF
2 changed files with 43 additions and 35 deletions

View File

@ -10,10 +10,10 @@ use anyhow::{bail, Result};
use libpt_log::{debug, error, trace, warn};
use std::io::{prelude::*, Read, SeekFrom};
const BYTES_PER_LINE: usize = 16;
const LINE_SEP_HORIZ: char = '─';
const LINE_SEP_VERT: char = '│';
const CHAR_BORDER: &'static str = "|";
pub const BYTES_PER_LINE: usize = 16;
pub const LINE_SEP_HORIZ: char = '─';
pub const LINE_SEP_VERT: char = '│';
pub const CHAR_BORDER: &'static str = "|";
#[derive(Debug)]
pub struct HeduConfig {
@ -70,14 +70,12 @@ impl DataSource for std::fs::File {
}
}
pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
// prepare some variables
pub fn dump(data: &mut dyn DataSource, config: &mut HeduConfig) -> Result<()> {
// skip a given number of bytes
if config.skip > 0 {
data.skip(config.skip)?;
config.data_idx += config.skip;
adjust_data_idx(&mut config);
adjust_data_idx(config);
debug!("Skipped {}", humanbytes(config.skip));
}
@ -95,7 +93,7 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
config.display();
// data dump loop
rd_data(data, &mut config)?;
rd_data(data, config)?;
while config.len > 0 {
config.display_buf += &format!("{:08X} {LINE_SEP_VERT} ", config.data_idx);
for i in 0..config.len {
@ -129,7 +127,7 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
}
// after line logic
rd_data(data, &mut config)?;
rd_data(data, config)?;
config.alt_buf ^= 1; // toggle the alt buf
if config.buf[0] == config.buf[1] && config.len == BYTES_PER_LINE && !config.show_identical
{
@ -139,7 +137,7 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
);
let start_line = config.data_idx;
while config.buf[0] == config.buf[1] && config.len == BYTES_PER_LINE {
rd_data(data, &mut config)?;
rd_data(data, config)?;
}
config.alt_buf ^= 1; // toggle the alt buf (now that we have a not same line)
config.display_buf += &format!(

View File

@ -18,7 +18,7 @@ use libpt::{bintols::hedu::*, log::*};
use clap::Parser;
use clap_verbosity_flag::{InfoLevel, Verbosity};
use std::{fs::File, io::IsTerminal};
use std::{fs::File, io::IsTerminal, path::PathBuf};
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
@ -87,7 +87,7 @@ pub struct Cli {
///
/// If left empty or set as "-", the program will read from stdin.
// TODO: take many sources #60
pub data_source: Option<String>,
pub data_source: Vec<String>,
}
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
@ -96,36 +96,46 @@ pub struct Cli {
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
fn main() {
let cli = cli_parse();
let mut source: Box<dyn DataSource>;
if cli.data_source.is_some() && cli.data_source.clone().is_some_and(|val| val != "-") {
let data_source = cli.data_source.unwrap();
trace!("Trying to open '{}'", data_source);
source = match File::open(&data_source) {
Ok(file) => Box::new(file),
Err(err) => {
error!("Could not open file '{}': {err}", data_source);
std::process::exit(1);
let mut cli = cli_parse();
let mut sources: Vec<Box<dyn DataSource>> = Vec::new();
if cli.data_source.len() > 0 && cli.data_source[0] != "-" {
for data_source in &cli.data_source {
let data_source: PathBuf = PathBuf::from(data_source);
if !data_source.is_file() {
debug!("Not a regular file'{:?}'", data_source);
// std::process::exit(1);
continue
}
};
trace!("Trying to open '{:?}'", data_source);
match File::open(&data_source) {
Ok(file) => sources.push(Box::new(file)),
Err(err) => {
error!("Could not open '{:?}': {err}", data_source);
std::process::exit(1);
}
};
}
} else {
trace!("Trying to open stdout");
trace!("Trying to open stdin");
let stdin = std::io::stdin();
if stdin.is_terminal() {
warn!("Refusing to dump from interactive terminal");
std::process::exit(2)
}
source = Box::new(stdin);
// just for the little header
cli.data_source = Vec::new();
cli.data_source.push(format!("stdin"));
sources.push(Box::new(stdin));
}
match dump(
&mut *source,
HeduConfig::new(cli.chars, cli.skip, cli.show_identical, cli.limit),
) {
Ok(_) => (),
Err(err) => {
error!("Could not dump data of file: {err}");
std::process::exit(3);
for (i, source) in sources.iter_mut().enumerate() {
println!("{:=^59}", format!(" {} ", cli.data_source[i]));
let mut config = HeduConfig::new(cli.chars, cli.skip, cli.show_identical, cli.limit);
match dump(&mut **source, &mut config) {
Ok(_) => (),
Err(err) => {
error!("Could not dump data of file: {err}");
std::process::exit(3);
}
}
}
}