Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

experiment: Sparse file support #185

Draft
wants to merge 27 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cb6f791
Add generic `Read` variant to `Input`
sharifhsn Dec 7, 2022
c08d259
breaking: Accept `Input` instead of `impl Read` for `print_all`
sharifhsn Dec 7, 2022
bc5172d
Merge branch 'master' into sparse
sharifhsn Dec 7, 2022
92fadee
Extend generic `Input` to rest of repository
sharifhsn Dec 8, 2022
4beb3f2
Implement buggy sparse file support on Linux
sharifhsn Dec 8, 2022
98029d0
Bump MSRV
sharifhsn Dec 8, 2022
c2818d1
Support 32-bit architecture
sharifhsn Dec 8, 2022
327eb20
Conditionally compile imports
sharifhsn Dec 8, 2022
4932563
Add simple error handling
sharifhsn Dec 8, 2022
063f875
Fully qualify names when possible for legibility
sharifhsn Dec 8, 2022
af4cc98
`cargo fmt`
sharifhsn Dec 8, 2022
6e9243b
Handle `ENXIO`, which fixes fully sparse files
sharifhsn Dec 8, 2022
5de6d69
Hack position to correct
sharifhsn Dec 8, 2022
7b9255c
Refactor and remove `BufReader`
sharifhsn Dec 8, 2022
ca31e84
Only call `sparse_check` on Linux
sharifhsn Dec 8, 2022
5f0dfdb
`cargo fmt` and 32-bit arch
sharifhsn Dec 8, 2022
6819765
`cargo fmt`
sharifhsn Dec 8, 2022
e8da51f
Implement character table control and codepage 437 option
sharifhsn Jun 13, 2023
2265f91
Use hyphens instead of underscores
sharifhsn Jun 13, 2023
90c95c8
Close quotation in help text
sharifhsn Jun 13, 2023
fede940
Add default value for character table
sharifhsn Jun 13, 2023
ed21210
Make `CharTable` non-exhaustive
sharifhsn Jun 13, 2023
37f4d44
Rename `CharTable` to `CharacterTable`
sharifhsn Jun 13, 2023
adbca66
Remove old `as_char` implementation
sharifhsn Jun 13, 2023
4d4d589
Attribute original author of CP437
sharifhsn Jun 13, 2023
9c0fd7e
Merge branch 'cp437' of https://github.com/sharifhsn/hexyl into cp437
sharifhsn Jun 13, 2023
70257d5
Merge branch 'cp437' into sparse
sharifhsn Jun 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions examples/simple.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::io;

use hexyl::{BorderStyle, PrinterBuilder};
use hexyl::{BorderStyle, Input, PrinterBuilder};

fn main() {
let input = vec![
Expand All @@ -20,5 +20,7 @@ fn main() {
.num_panels(2)
.group_size(1)
.build();
printer.print_all(&input[..]).unwrap();
printer
.print_all(Input::Generic(Box::new(io::Cursor::new(input))))
.unwrap();
}
36 changes: 31 additions & 5 deletions src/bin/hexyl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use thiserror::Error as ThisError;

use terminal_size::terminal_size;

use hexyl::{Base, BorderStyle, Endianness, Input, PrinterBuilder};
use hexyl::{Base, BorderStyle, CharacterTable, Endianness, Input, PrinterBuilder};

const DEFAULT_BLOCK_SIZE: i64 = 512;

Expand Down Expand Up @@ -209,6 +209,18 @@ fn run() -> Result<()> {
.hide(true)
.help("An alias for '--endianness=little'."),
)
.arg(
Arg::new("character-table")
.long("character-table")
.value_name("FORMAT")
.value_parser(["codepage-437", "ascii-only"])
.default_value("ascii-only")
.help(
"The character table that should be used. 'ascii-only' \
will show dots for non-ASCII characters, and 'codepage-437' \
will use Code page 437 for those characters."
),
)
.arg(
Arg::new("base")
.short('b')
Expand Down Expand Up @@ -306,7 +318,7 @@ fn run() -> Result<()> {
.into())
};

let mut reader = if let Some(length) = matches
let reader = if let Some(length) = matches
.get_one::<String>("length")
.or_else(|| matches.get_one::<String>("bytes"))
.or_else(|| matches.get_one::<String>("count"))
Expand All @@ -318,9 +330,11 @@ fn run() -> Result<()> {
})
.transpose()?
{
Box::new(reader.take(length))
Input::Generic(Box::new(reader.take(length)))
} else if let Input::File(_) = reader {
reader
} else {
reader.into_inner()
Input::Generic(reader.into_inner())
};

let show_color = match matches.get_one::<String>("color").map(String::as_ref) {
Expand Down Expand Up @@ -466,6 +480,17 @@ fn run() -> Result<()> {
("big", _) => Endianness::Big,
_ => unreachable!(),
};

let character_table = match matches
.get_one::<String>("character-table")
.unwrap()
.as_ref()
{
"ascii-only" => CharacterTable::AsciiOnly,
"codepage-437" => CharacterTable::CP437,
_ => unreachable!(),
};

let stdout = io::stdout();
let mut stdout_lock = BufWriter::new(stdout.lock());

Expand All @@ -479,9 +504,10 @@ fn run() -> Result<()> {
.group_size(group_size)
.with_base(base)
.endianness(endianness)
.character_table(character_table)
.build();
printer.display_offset(skip_offset + display_offset);
printer.print_all(&mut reader).map_err(|e| anyhow!(e))?;
printer.print_all(reader).map_err(|e| anyhow!(e))?;

Ok(())
}
Expand Down
8 changes: 8 additions & 0 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ use std::io::{self, copy, sink, Read, Seek, SeekFrom};
pub enum Input<'a> {
File(fs::File),
Stdin(io::StdinLock<'a>),
Generic(Box<dyn Read>),
}

impl<'a> Read for Input<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match *self {
Input::File(ref mut file) => file.read(buf),
Input::Stdin(ref mut stdin) => stdin.read(buf),
Input::Generic(ref mut reader) => reader.read(buf),
}
}
}
Expand Down Expand Up @@ -51,6 +53,11 @@ impl<'a> Seek for Input<'a> {
pos,
"STDIN only supports seeking forward with a relative offset",
),
Input::Generic(ref mut reader) => try_skip(
reader,
pos,
"This reader only supports seeking forward with a relative offset",
),
}
}
}
Expand All @@ -60,6 +67,7 @@ impl<'a> Input<'a> {
match self {
Input::File(file) => Box::new(file),
Input::Stdin(stdin) => Box::new(stdin),
Input::Generic(reader) => reader,
}
}
}