mirror of
https://github.com/sharkdp/hexyl.git
synced 2026-10-26 20:16:34 +00:00
hexyl: add display offset option
This commit is contained in:
1 parent
23f199ffbd
commit
d64053771c
2 files changed
+61
-12
No files matched your search
+23
-7
@@ -69,6 +69,14 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.possible_values(&["unicode", "ascii", "none"])
|
||||
.default_value("unicode")
|
||||
.help("Whether to draw a border with unicode or ASCII characters, or none at all"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("display_offset")
|
||||
.short("o")
|
||||
.long("display-offset")
|
||||
.takes_value(true)
|
||||
.value_name("OFFSET")
|
||||
.help("Add OFFSET to the displayed file position."),
|
||||
);
|
||||
|
||||
let matches = app.get_matches_safe()?;
|
||||
@@ -82,13 +90,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let length_arg = matches.value_of("length").or(matches.value_of("bytes"));
|
||||
|
||||
if let Some(length) = length_arg.and_then(|n| {
|
||||
if n.starts_with("0x") {
|
||||
u64::from_str_radix(n.trim_start_matches("0x"), 16).ok()
|
||||
} else {
|
||||
n.parse::<u64>().ok()
|
||||
}
|
||||
}) {
|
||||
if let Some(length) = length_arg.and_then(parse_hex_or_int) {
|
||||
reader = Box::new(reader.take(length));
|
||||
}
|
||||
|
||||
@@ -106,6 +108,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let squeeze = !matches.is_present("nosqueezing");
|
||||
|
||||
let display_offset = matches
|
||||
.value_of("display_offset")
|
||||
.and_then(parse_hex_or_int)
|
||||
.unwrap_or(0);
|
||||
|
||||
// Set up Ctrl-C handler
|
||||
let cancelled = Arc::new(AtomicBool::new(false));
|
||||
let c = cancelled.clone();
|
||||
@@ -119,6 +126,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut stdout_lock = stdout.lock();
|
||||
|
||||
let mut printer = Printer::new(&mut stdout_lock, show_color, border_style, squeeze);
|
||||
printer.display_offset(display_offset as usize);
|
||||
printer.print_all(&mut reader, Some(cancelled))?;
|
||||
|
||||
Ok(())
|
||||
@@ -148,3 +156,11 @@ fn main() {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_hex_or_int(n: &str) -> Option<u64> {
|
||||
if n.starts_with("0x") {
|
||||
u64::from_str_radix(n.trim_start_matches("0x"), 16).ok()
|
||||
} else {
|
||||
n.parse::<u64>().ok()
|
||||
}
|
||||
}
|
||||
+38
-5
@@ -155,6 +155,7 @@ pub struct Printer<'a, Writer: Write> {
|
||||
byte_hex_table: Vec<String>,
|
||||
byte_char_table: Vec<String>,
|
||||
squeezer: Squeezer,
|
||||
display_offset: usize,
|
||||
}
|
||||
|
||||
impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||
@@ -193,9 +194,15 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||
})
|
||||
.collect(),
|
||||
squeezer: Squeezer::new(use_squeeze),
|
||||
display_offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_offset(&mut self, display_offset: usize) -> &mut Self {
|
||||
self.display_offset = display_offset;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn header(&mut self) {
|
||||
if let Some(border_elements) = self.border_style.header_elems() {
|
||||
let h = border_elements.horizontal_line;
|
||||
@@ -241,7 +248,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||
}
|
||||
|
||||
let style = COLOR_OFFSET.normal();
|
||||
let byte_index = format!("{:08x}", self.idx - 1);
|
||||
let byte_index = format!("{:08x}", (self.idx - 1) + self.display_offset);
|
||||
let formatted_string = if self.show_color {
|
||||
format!("{}", style.paint(byte_index))
|
||||
} else {
|
||||
@@ -456,19 +463,45 @@ mod tests {
|
||||
#[test]
|
||||
fn empty_file_passes() {
|
||||
let input = io::empty();
|
||||
let expected_string = "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
|
||||
let expected_string =
|
||||
"┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
|
||||
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
|
||||
".to_owned();
|
||||
"
|
||||
.to_owned();
|
||||
assert_print_all_output(input, expected_string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_input_passes() {
|
||||
let input = io::Cursor::new(b"spam");
|
||||
let expected_string = "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
|
||||
let expected_string =
|
||||
"┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
|
||||
│00000000│ 73 70 61 6d ┊ │spam ┊ │
|
||||
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
|
||||
".to_owned();
|
||||
"
|
||||
.to_owned();
|
||||
assert_print_all_output(input, expected_string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_offset() {
|
||||
let input = io::Cursor::new(b"spamspamspamspamspam");
|
||||
let expected_string =
|
||||
"┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
|
||||
│deadbeef│ 73 70 61 6d 73 70 61 6d ┊ 73 70 61 6d 73 70 61 6d │spamspam┊spamspam│
|
||||
│deadbeff│ 73 70 61 6d ┊ │spam ┊ │
|
||||
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
|
||||
"
|
||||
.to_owned();
|
||||
|
||||
let mut output = vec![];
|
||||
let mut printer: Printer<Vec<u8>> =
|
||||
Printer::new(&mut output, false, BorderStyle::Unicode, true);
|
||||
printer.display_offset(0xdeadbeef);
|
||||
|
||||
printer.print_all(input, None).unwrap();
|
||||
|
||||
let actual_string: &str = str::from_utf8(&output).unwrap();
|
||||
assert_eq!(actual_string, expected_string)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user