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 {
85 std::slice::from_raw_parts(
86 &test_header as *const _ as *const u8,
87 std::mem::size_of::<TraceEventHeader>(),
88 )
89 };
90
91 let result = bridge.process_ringbuf_segment(header_bytes, &trace_context);
93
94 assert!(result.is_ok());
96 assert!(result.unwrap().is_none());
97 }
98}