use ghostscope_protocol::{ParsedTraceEvent, StreamingTraceParser, TraceContext};
use tracing::debug;
pub struct StreamingParserBridge {
parser: StreamingTraceParser,
}
impl StreamingParserBridge {
pub fn new() -> Self {
Self {
parser: StreamingTraceParser::new(),
}
}
pub fn process_ringbuf_segment(
&mut self,
segment_data: &[u8],
trace_context: &TraceContext,
) -> Result<Option<ParsedTraceEvent>, String> {
let parsed_event = self.parser.process_segment(segment_data, trace_context)?;
if let Some(trace_event) = parsed_event {
debug!(
"Completed trace event: trace_id={}, {} instructions",
trace_event.trace_id,
trace_event.instructions.len()
);
Ok(Some(trace_event))
} else {
Ok(None)
}
}
pub fn reset(&mut self) {
self.parser.reset();
}
pub fn get_parse_state(&self) -> &ghostscope_protocol::ParseState {
self.parser.get_state()
}
}
impl Default for StreamingParserBridge {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use ghostscope_protocol::TraceContext;
#[test]
fn test_streaming_parser_bridge() {
let mut bridge = StreamingParserBridge::new();
let trace_context = TraceContext::new();
use ghostscope_protocol::{consts, TraceEventHeader};
let test_header = TraceEventHeader {
magic: consts::MAGIC,
};
let header_bytes = unsafe {
std::slice::from_raw_parts(
&test_header as *const _ as *const u8,
std::mem::size_of::<TraceEventHeader>(),
)
};
let result = bridge.process_ringbuf_segment(header_bytes, &trace_context);
assert!(result.is_ok());
assert!(result.unwrap().is_none());
}
}