diff --git a/Cargo.lock b/Cargo.lock index 4006bbb..e4bc9fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,6 +446,7 @@ dependencies = [ "encoding_rs", "evalexpr", "hex", + "memchr", "mmap-io", "ratatui", "regex", diff --git a/Cargo.toml b/Cargo.toml index 2332215..7e07a69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ license = "GPL-3.0-or-later" keywords = ["hex-editor", "reverse-engineering", "binary", "pe", "elf"] categories = ["command-line-utilities", "security"] - [dependencies] arboard = { version = "3", default-features = false } clap = { version = "4.5.49", features = ["derive"] } @@ -19,13 +18,14 @@ directories-next = "2.0.0" encoding_rs = "0.8.35" evalexpr = "13.1.*" hex = "0.4.3" +memchr = "2.8.0" +mmap-io = "0.9.4" ratatui = "0.30.0" regex = "1.11.2" serde = { version = "1.0.228", features = ["derive"] } shell-words = "1.1.0" -tui-input = "0.15.0" -mmap-io = { version = "0.9.4" } toml = "1.0.1" +tui-input = "0.15.0" # The profile that 'dist' will build with [profile.dist] diff --git a/src/hex/search.rs b/src/hex/search.rs index f7a7012..f8bfd85 100644 --- a/src/hex/search.rs +++ b/src/hex/search.rs @@ -51,40 +51,27 @@ pub fn hex_string_to_u8(hex_string: &str) -> Option> { pub fn search>(app: &mut App, needle: T) -> Option { let text = needle.as_ref(); - let siz = text.len(); let filesize = app.file_info.size; let buffer = app.file_info.get_buffer(); - if filesize == 0 { + if filesize == 0 || text.is_empty() { return None; } - let search_forward = || { - for (i, win) in buffer[app.hex_view.offset + 1..].windows(siz).enumerate() { - if win == text { - return Some(app.hex_view.offset + i + 1); - } - } - None - }; - - let search_backward = || { - for (i, win) in buffer[0..app.hex_view.offset] - .windows(siz) - .rev() - .enumerate() - { - if win == text { - return Some(app.hex_view.offset - i - text.len()); - } - } - None - }; - let ofs = if app.hex_view.search.direction == SearchDirection::Forward { - search_forward() + let start = app.hex_view.offset.checked_add(1)?; + if start < filesize { + memchr::memmem::find(buffer.get(start..)?, text).map(|pos| start + pos) + } else { + None + } } else { - search_backward() + let end = app.hex_view.offset; + if end > 0 { + memchr::memmem::rfind(buffer.get(..end)?, text) + } else { + None + } }; if ofs.is_some() { @@ -93,28 +80,10 @@ pub fn search>(app: &mut App, needle: T) -> Option { // ofs is None, check wrap setting if app.config.search_wrap { - let search_wrap_forward = || { - for (i, win) in buffer.windows(siz).enumerate() { - if win == text { - return Some(i); - } - } - None - }; - - let search_wrap_backward = || { - for (i, win) in buffer.windows(siz).rev().enumerate() { - if win == text { - return Some(filesize - i - text.len()); - } - } - None - }; - let ofs = if app.hex_view.search.direction == SearchDirection::Forward { - search_wrap_forward() + memchr::memmem::find(buffer, text) } else { - search_wrap_backward() + memchr::memmem::rfind(buffer, text) }; if ofs.is_some() { @@ -126,24 +95,6 @@ pub fn search>(app: &mut App, needle: T) -> Option { None } -// pub fn search_back>(app: &mut App, needle: T) -> Option { -// let text = needle.as_ref(); -// let siz = text.len(); -// let buffer = app.file_info.get_buffer(); -// for (i, win) in buffer[0..app.hex_view.offset] -// .windows(siz) -// .rev() -// .enumerate() -// { -// if win == text { -// return Some(app.hex_view.offset - i - 1); -// } -// } -// -// crate::beep!(); -// None -// } - // string // hex pub fn dialog_search_draw(app: &mut App, frame: &mut Frame) {