ghostscope_ui/components/ebpf_panel/output/
streaming_parser_bridge.rs1use ghostscope_protocol::{ParsedTraceEvent, StreamingTraceParser, TraceContext};
7use tracing::debug;
8
9pub struct StreamingParserBridge {
11 parser: StreamingTraceParser,
12}
13
14impl StreamingParserBridge {
15 pub fn new() -> Self {
17 Self {
18 parser: StreamingTraceParser::new(),
19 }
20 }
21
22 pub fn process_ringbuf_segment(
27 &mut self,
28 segment_data: &[u8],
29 trace_context: &TraceContext,
30 ) -> Result<Option<ParsedTraceEvent>, String> {
31 let parsed_event = self.parser.process_segment(segment_data, trace_context)?;
33
34 if let Some(trace_event) = parsed_event {
35 debug!(
36 "Completed trace event: trace_id={}, {} instructions",
37 trace_event.trace_id,
38 trace_event.instructions.len()
39 );
40
41 Ok(Some(trace_event))
42 } else {
43 Ok(None)
45 }
46 }
47
48 pub fn reset(&mut self) {
50 self.parser.reset();
51 }
52
53 pub fn get_parse_state(&self) -> &ghostscope_protocol::ParseState {
55 self.parser.get_state()
56 }
57}
58
59impl Default for StreamingParserBridge {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use ghostscope_protocol::TraceContext;
69
70 #[test]
71 fn test_streaming_parser_bridge() {
72 let mut bridge = StreamingParserBridge::new();
73 let trace_context = TraceContext::new();
74
75 use ghostscope_protocol::{consts, TraceEventHeader};
77 let test_header = TraceEventHeader {
78 magic: consts::MAGIC,
79 };
80
81 let header_bytes = unsafe {
83 std::slice::from_raw_parts(
84 &test_header as *const _ as *const u8,
85 std::mem::size_of::<TraceEventHeader>(),
86 )
87 };
88
89 let result = bridge.process_ringbuf_segment(header_bytes, &trace_context);
91
92 assert!(result.is_ok());
94 assert!(result.unwrap().is_none());
95 }
96}