Skip to content

Commit e9cc9f0

Browse files
committed
add new option to skip n bytes before searching
1 parent 72c8a24 commit e9cc9f0

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

src/lib.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ use utils::{file, search};
1010
use crate::utils::{print_hexdump_output, PatternType};
1111

1212
pub fn setup_args<'a>() -> ArgMatches<'a> {
13+
let integer_validator = |value: String| match value.parse::<usize>() {
14+
Ok(_) => Ok(()),
15+
Err(_) => Err(String::from("the value needs to be a valid integer")),
16+
};
17+
1318
App::new("grep_bin")
1419
.version(clap::crate_version!())
1520
.author(clap::crate_authors!())
@@ -45,23 +50,28 @@ All of these byte sequence are valid: f9b4ca, F9B4CA and f9B4Ca",
4550
Examples of input: jpg, mp3, exe",
4651
),
4752
)
48-
.arg(Arg::with_name("context_bytes_size")
49-
.short("c")
50-
.default_value("16")
51-
.validator(|value| {
52-
match value.parse::<usize>() {
53-
Ok(_) => Ok(()),
54-
Err(_) => Err(String::from("the value needs to be a valid integer")),
55-
}
56-
})
57-
.long_help("Defines the number of bytes that will be printed in each line.")
58-
)
53+
.arg(
54+
Arg::with_name("context_bytes_size")
55+
.short("c")
56+
.default_value("16")
57+
.validator(integer_validator)
58+
.long_help("Defines the number of bytes that will be printed in each line."),
59+
)
5960
.arg(
6061
Arg::with_name("print_only")
6162
.short("p")
6263
.long("print-only")
6364
.help("Prints only the file name that contais the match."),
6465
)
66+
.arg(
67+
Arg::with_name("skip_bytes")
68+
.short("s")
69+
.long("skip-bytes")
70+
.default_value("0")
71+
.takes_value(true)
72+
.validator(integer_validator)
73+
.help("Skip n bytes before searching."),
74+
)
6575
.settings(&[AppSettings::ArgRequiredElseHelp, AppSettings::ColoredHelp])
6676
.get_matches()
6777
}
@@ -90,6 +100,7 @@ pub fn run(args: ArgMatches) {
90100
.unwrap()
91101
.parse()
92102
.unwrap();
103+
let skip_bytes: u64 = args.value_of("skip_bytes").unwrap().parse().unwrap();
93104

94105
for filename in files {
95106
let mut searcher = search::Searcher::new(&pattern, context_bytes_size, skip_bytes);

src/utils/search.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::fs::File;
2-
use std::io::{BufReader, Read};
2+
use std::io::{BufReader, Read, Seek, SeekFrom};
33
use std::ops::Range;
44

55
#[derive(Debug, Clone)]
@@ -95,25 +95,27 @@ pub struct Searcher<'a> {
9595
pattern: &'a [u8],
9696
matches: Matches,
9797
context_bytes_size: usize,
98+
skip_bytes: u64,
9899
}
99100

100101
impl<'a> Searcher<'a> {
101102
const BUFFER_SIZE: usize = 8192;
102103

103-
pub fn new(pattern: &'a [u8], context_bytes_size: usize) -> Self {
104+
pub fn new(pattern: &'a [u8], context_bytes_size: usize, skip_bytes: u64) -> Self {
104105
Self {
105106
pattern,
106107
matches: Matches::new(pattern.len(), context_bytes_size),
107108
context_bytes_size,
109+
skip_bytes,
108110
}
109111
}
110112

111113
pub fn search_in_file(&mut self, filepath: &str) -> std::io::Result<()> {
112-
let file = File::open(filepath)?;
114+
let mut file = File::open(filepath)?;
113115
let file_size = file.metadata().unwrap().len() as usize;
114116

117+
let mut pos_in_file = file.seek(SeekFrom::Start(self.skip_bytes)).unwrap_or(0) as usize;
115118
let mut reader = BufReader::new(file);
116-
let mut pos_in_file = 0;
117119

118120
if file_size < self.context_bytes_size {
119121
self.context_bytes_size = file_size;

0 commit comments

Comments
 (0)