blob: c4e1830685e444d2f6636077bae2a3e586e01216 [file] [edit]
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0
use zerocopy::FromBytes;
use zfmt::events::{DebugMessage, EventHeader, StreamStart};
use zfmt::leb128;
use zfmt::FixedBuf;
use zfmt::Write;
/// Renders a serialized `zfmt` event into a string and passes it to the callback.
///
/// `N` is the size of the temporary formatting buffer.
/// Returns the number of bytes consumed from `event` on success, or `None` on failure.
pub fn render_event<const N: usize>(event: &[u8], buf: &mut FixedBuf<N>) -> Option<usize> {
let mut i = 0usize;
let mut rest = event;
loop {
let (tag, mut next) = u32::read_from_prefix(rest).ok()?;
i += 4;
let (len, n) = leb128::decode(next)?;
i += n;
next = next.get(n..)?;
let len = usize::try_from(len).ok()?;
i += len;
match tag {
StreamStart::ZFMT_TAG => {
let _ = buf.write_str("[StreamStart Event]");
return Some(i);
}
EventHeader::ZFMT_TAG => {
let eh = EventHeader::from_bytes(next.get(..len)?)?;
let _ = eh.format_into(buf);
let _ = buf.write_char(' ');
}
DebugMessage::ZFMT_TAG => {
let (msg_len, n) = leb128::decode(next)?;
let msg_len = usize::try_from(msg_len).ok()?;
let end = n.checked_add(msg_len)?;
let msg_bytes = next.get(n..end)?;
// nosemgrep
let msg = unsafe {
// SAFETY: the DebugMessage is guaranteed to contain a string.
core::str::from_utf8_unchecked(msg_bytes)
};
let _ = buf.write_str(msg);
return Some(i);
}
_ => {
// Unknown tag, silently consume.
//pw_log::error!("Unknown tag {:08x} with {} bytes", tag, len);
}
}
rest = next.get(len..)?;
}
}