use packet_dissector_core::packet::{DissectBuffer, Packet};
use super::app::App;
use super::state::FilterProgress;
use crate::filter_expr::FilterExpr;
impl App {
pub(super) fn apply_filter(&mut self) {
self.filter.error_message = None;
let expr = match FilterExpr::parse(&self.filter.buf.input) {
Ok(expr) => expr,
Err(msg) => {
self.filter.error_message = Some(msg);
return;
}
};
self.filter.applied = self.filter.buf.input.clone();
if expr.is_none() {
self.filtered_indices = (0..self.indices.len()).collect();
self.summary_cache.clear();
self.packet_list.selected = 0;
self.packet_list.scroll_offset = 0;
self.load_selected();
self.hex_dump.scroll_offset = 0;
return;
}
self.filter_progress = Some(FilterProgress {
expr,
cursor: 0,
results: Vec::new(),
});
}
const FILTER_CHUNK_SIZE: usize = 10_000;
pub fn filter_tick(&mut self) -> bool {
let total = self.indices.len();
let progress = match &mut self.filter_progress {
Some(p) => p,
None => return false,
};
let end = (progress.cursor + Self::FILTER_CHUNK_SIZE).min(total);
let pn_only = progress
.expr
.as_ref()
.is_some_and(|e| e.is_packet_number_only());
let mut dissect_buf = DissectBuffer::new();
for i in progress.cursor..end {
let number = (i as u64) + 1; let matches = if let Some(expr) = &progress.expr {
if pn_only {
let buf = dissect_buf.clear_into();
let empty_pkt = Packet::new(buf, &[]);
expr.matches_with_number(&empty_pkt, number)
} else {
let index = &self.indices[i];
if let Some(data) = self.capture.packet_data(index) {
let buf = dissect_buf.clear_into();
if self
.registry
.dissect_with_link_type(data, index.link_type as u32, buf)
.is_ok()
{
let packet = Packet::new(buf, data);
expr.matches_with_number(&packet, number)
} else {
false
}
} else {
false
}
}
} else {
true
};
if matches {
progress.results.push(i);
}
}
progress.cursor = end;
if progress.cursor >= total {
let results = match std::mem::take(&mut self.filter_progress) {
Some(fp) => fp.results,
None => Vec::new(),
};
self.filtered_indices = results;
self.summary_cache.clear();
self.packet_list.selected = 0;
self.packet_list.scroll_offset = 0;
self.load_selected();
self.hex_dump.scroll_offset = 0;
return false;
}
true
}
}