mirror of
https://github.com/sharkdp/hexyl.git
synced 2026-10-30 09:05:54 +00:00
Merge pull request #189 from RinHizakura/master
Support both little and big endian dump
This commit is contained in:
3 files changed
+130
-8
No files matched your search
+38
-3
@@ -17,7 +17,7 @@ use thiserror::Error as ThisError;
|
|||||||
|
|
||||||
use terminal_size::terminal_size;
|
use terminal_size::terminal_size;
|
||||||
|
|
||||||
use hexyl::{Base, BorderStyle, Input, PrinterBuilder};
|
use hexyl::{Base, BorderStyle, Endianness, Input, PrinterBuilder};
|
||||||
|
|
||||||
const DEFAULT_BLOCK_SIZE: i64 = 512;
|
const DEFAULT_BLOCK_SIZE: i64 = 512;
|
||||||
|
|
||||||
@@ -174,10 +174,34 @@ fn run() -> Result<()> {
|
|||||||
.value_name("N")
|
.value_name("N")
|
||||||
.help(
|
.help(
|
||||||
"Number of bytes/octets that should be grouped together. \
|
"Number of bytes/octets that should be grouped together. \
|
||||||
Possible group sizes are 1, 2, 4, 8. The default is 1. \
|
Possible group sizes are 1, 2, 4, 8. The default is 1. You \
|
||||||
'--groupsize can be used as an alias (xxd-compatibility).",
|
can use the '--endianness' option to control the ordering of \
|
||||||
|
the bytes within a group. '--groupsize' can be used as an \
|
||||||
|
alias (xxd-compatibility).",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("endianness")
|
||||||
|
.long("endianness")
|
||||||
|
.num_args(1)
|
||||||
|
.value_name("FORMAT")
|
||||||
|
.value_parser(["big", "little"])
|
||||||
|
.default_value("big")
|
||||||
|
.help(
|
||||||
|
"Whether to print out groups in little-endian or big-endian \
|
||||||
|
format. This option only has an effect if the '--group-size' \
|
||||||
|
is larger than 1. '-e' can be used as an alias for \
|
||||||
|
'--endianness=little'.",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("little_endian_format")
|
||||||
|
.short('e')
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.overrides_with("endianness")
|
||||||
|
.hide(true)
|
||||||
|
.help("An alias for '--endianness=little'."),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("base")
|
Arg::new("base")
|
||||||
.short('b')
|
.short('b')
|
||||||
@@ -425,6 +449,16 @@ fn run() -> Result<()> {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let little_endian_format = *matches.get_one::<bool>("little_endian_format").unwrap();
|
||||||
|
let endianness = matches.get_one::<String>("endianness");
|
||||||
|
let endianness = match (
|
||||||
|
endianness.map(|s| s.as_ref()).unwrap(),
|
||||||
|
little_endian_format,
|
||||||
|
) {
|
||||||
|
(_, true) | ("little", _) => Endianness::Little,
|
||||||
|
("big", _) => Endianness::Big,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
let mut stdout_lock = BufWriter::new(stdout.lock());
|
let mut stdout_lock = BufWriter::new(stdout.lock());
|
||||||
|
|
||||||
@@ -437,6 +471,7 @@ fn run() -> Result<()> {
|
|||||||
.num_panels(panels)
|
.num_panels(panels)
|
||||||
.group_size(group_size)
|
.group_size(group_size)
|
||||||
.with_base(base)
|
.with_base(base)
|
||||||
|
.endianness(endianness)
|
||||||
.build();
|
.build();
|
||||||
printer.display_offset(skip_offset + display_offset);
|
printer.display_offset(skip_offset + display_offset);
|
||||||
printer.print_all(&mut reader).map_err(|e| anyhow!(e))?;
|
printer.print_all(&mut reader).map_err(|e| anyhow!(e))?;
|
||||||
|
|||||||
+40
-1
@@ -29,6 +29,11 @@ pub enum ByteCategory {
|
|||||||
NonAscii,
|
NonAscii,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Endianness {
|
||||||
|
Little,
|
||||||
|
Big,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum Squeezer {
|
enum Squeezer {
|
||||||
Print,
|
Print,
|
||||||
@@ -159,6 +164,7 @@ pub struct PrinterBuilder<'a, Writer: Write> {
|
|||||||
panels: u64,
|
panels: u64,
|
||||||
group_size: u8,
|
group_size: u8,
|
||||||
base: Base,
|
base: Base,
|
||||||
|
endianness: Endianness,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
||||||
@@ -173,6 +179,7 @@ impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
|||||||
panels: 2,
|
panels: 2,
|
||||||
group_size: 1,
|
group_size: 1,
|
||||||
base: Base::Hexadecimal,
|
base: Base::Hexadecimal,
|
||||||
|
endianness: Endianness::Big,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +223,11 @@ impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn endianness(mut self, endianness: Endianness) -> Self {
|
||||||
|
self.endianness = endianness;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Printer<'a, Writer> {
|
pub fn build(self) -> Printer<'a, Writer> {
|
||||||
Printer::new(
|
Printer::new(
|
||||||
self.writer,
|
self.writer,
|
||||||
@@ -227,6 +239,7 @@ impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
|||||||
self.panels,
|
self.panels,
|
||||||
self.group_size,
|
self.group_size,
|
||||||
self.base,
|
self.base,
|
||||||
|
self.endianness,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,6 +267,8 @@ pub struct Printer<'a, Writer: Write> {
|
|||||||
group_size: u8,
|
group_size: u8,
|
||||||
/// The number of digits used to write the base.
|
/// The number of digits used to write the base.
|
||||||
base_digits: u8,
|
base_digits: u8,
|
||||||
|
/// Whether to show groups in little or big endian format.
|
||||||
|
endianness: Endianness,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Writer: Write> Printer<'a, Writer> {
|
impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||||
@@ -267,6 +282,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
panels: u64,
|
panels: u64,
|
||||||
group_size: u8,
|
group_size: u8,
|
||||||
base: Base,
|
base: Base,
|
||||||
|
endianness: Endianness,
|
||||||
) -> Printer<'a, Writer> {
|
) -> Printer<'a, Writer> {
|
||||||
Printer {
|
Printer {
|
||||||
idx: 0,
|
idx: 0,
|
||||||
@@ -304,6 +320,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
Base::Decimal => 3,
|
Base::Decimal => 3,
|
||||||
Base::Hexadecimal => 2,
|
Base::Hexadecimal => 2,
|
||||||
},
|
},
|
||||||
|
endianness,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,8 +540,26 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reorder_buffer_to_little_endian(&self, buf: &mut Vec<u8>) {
|
||||||
|
let n = buf.len();
|
||||||
|
let group_sz = self.group_size as usize;
|
||||||
|
|
||||||
|
for idx in (0..n).step_by(group_sz) {
|
||||||
|
let remaining = n - idx;
|
||||||
|
let total = remaining.min(group_sz);
|
||||||
|
|
||||||
|
buf[idx..idx + total].reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_bytes(&mut self) -> io::Result<()> {
|
pub fn print_bytes(&mut self) -> io::Result<()> {
|
||||||
for (i, &b) in self.line_buf.clone().iter().enumerate() {
|
let mut buf = self.line_buf.clone();
|
||||||
|
|
||||||
|
if matches!(self.endianness, Endianness::Little) {
|
||||||
|
self.reorder_buffer_to_little_endian(&mut buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i, &b) in buf.iter().enumerate() {
|
||||||
self.print_byte(i, b)?;
|
self.print_byte(i, b)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -682,6 +717,7 @@ mod tests {
|
|||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
Base::Hexadecimal,
|
Base::Hexadecimal,
|
||||||
|
Endianness::Big,
|
||||||
);
|
);
|
||||||
|
|
||||||
printer.print_all(input).unwrap();
|
printer.print_all(input).unwrap();
|
||||||
@@ -736,6 +772,7 @@ mod tests {
|
|||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
Base::Hexadecimal,
|
Base::Hexadecimal,
|
||||||
|
Endianness::Big,
|
||||||
);
|
);
|
||||||
printer.display_offset(0xdeadbeef);
|
printer.display_offset(0xdeadbeef);
|
||||||
|
|
||||||
@@ -769,6 +806,7 @@ mod tests {
|
|||||||
4,
|
4,
|
||||||
1,
|
1,
|
||||||
Base::Hexadecimal,
|
Base::Hexadecimal,
|
||||||
|
Endianness::Big,
|
||||||
);
|
);
|
||||||
|
|
||||||
printer.print_all(input).unwrap();
|
printer.print_all(input).unwrap();
|
||||||
@@ -828,6 +866,7 @@ mod tests {
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
Base::Hexadecimal,
|
Base::Hexadecimal,
|
||||||
|
Endianness::Big,
|
||||||
);
|
);
|
||||||
|
|
||||||
printer.print_all(input).unwrap();
|
printer.print_all(input).unwrap();
|
||||||
|
|||||||
@@ -292,12 +292,12 @@ mod display_settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod group {
|
mod group_and_endianness {
|
||||||
use super::hexyl;
|
use super::hexyl;
|
||||||
use super::PrettyAssert;
|
use super::PrettyAssert;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn group_2_bytes() {
|
fn group_2_bytes_be() {
|
||||||
hexyl()
|
hexyl()
|
||||||
.arg("ascii")
|
.arg("ascii")
|
||||||
.arg("--color=never")
|
.arg("--color=never")
|
||||||
@@ -312,7 +312,23 @@ mod group {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn group_4_bytes() {
|
fn group_2_bytes_le() {
|
||||||
|
hexyl()
|
||||||
|
.arg("ascii")
|
||||||
|
.arg("--color=never")
|
||||||
|
.arg("--group-size=2")
|
||||||
|
.arg("--endianness=little")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(
|
||||||
|
"┌────────┬─────────────────────┬─────────────────────┬────────┬────────┐\n\
|
||||||
|
│00000000│ 3130 3332 3534 3736 ┊ 3938 6261 6463 0a65 │01234567┊89abcde_│\n\
|
||||||
|
└────────┴─────────────────────┴─────────────────────┴────────┴────────┘\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn group_4_bytes_be() {
|
||||||
hexyl()
|
hexyl()
|
||||||
.arg("ascii")
|
.arg("ascii")
|
||||||
.arg("--color=never")
|
.arg("--color=never")
|
||||||
@@ -327,7 +343,23 @@ mod group {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn group_8_bytes() {
|
fn group_4_bytes_le() {
|
||||||
|
hexyl()
|
||||||
|
.arg("ascii")
|
||||||
|
.arg("--color=never")
|
||||||
|
.arg("--group-size=4")
|
||||||
|
.arg("--endianness=little")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(
|
||||||
|
"┌────────┬───────────────────┬───────────────────┬────────┬────────┐\n\
|
||||||
|
│00000000│ 33323130 37363534 ┊ 62613938 0a656463 │01234567┊89abcde_│\n\
|
||||||
|
└────────┴───────────────────┴───────────────────┴────────┴────────┘\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn group_8_bytes_be() {
|
||||||
hexyl()
|
hexyl()
|
||||||
.arg("ascii")
|
.arg("ascii")
|
||||||
.arg("--color=never")
|
.arg("--color=never")
|
||||||
@@ -341,6 +373,22 @@ mod group {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn group_8_bytes_le() {
|
||||||
|
hexyl()
|
||||||
|
.arg("ascii")
|
||||||
|
.arg("--color=never")
|
||||||
|
.arg("--group-size=8")
|
||||||
|
.arg("--endianness=little")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(
|
||||||
|
"┌────────┬──────────────────┬──────────────────┬────────┬────────┐\n\
|
||||||
|
│00000000│ 3736353433323130 ┊ 0a65646362613938 │01234567┊89abcde_│\n\
|
||||||
|
└────────┴──────────────────┴──────────────────┴────────┴────────┘\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn group_size_plain() {
|
fn group_size_plain() {
|
||||||
hexyl()
|
hexyl()
|
||||||
|
|||||||
Reference in new issue
Block a user