#![forbid(unsafe_code)]
use get_protocol::LogFlags;
use get_protocol::LogLevel;
use get_protocol::LogType;
use get_protocol::TRACE_LOGGING_FIELDS_MAX_SIZE;
use get_protocol::TRACE_LOGGING_MESSAGE_MAX_SIZE;
use get_protocol::TRACE_LOGGING_NAME_MAX_SIZE;
use get_protocol::TRACE_LOGGING_TARGET_MAX_SIZE;
use get_protocol::TraceLoggingBufferOffset;
use get_protocol::TraceLoggingNotificationHeader;
use guid::Guid;
use zerocopy::IntoBytes;
fn truncate_slice(input: &[u8], len: usize) -> &[u8] {
if input.len() <= len {
input
} else {
&input[..len]
}
}
pub fn build_tracelogging_notification_buffer(
log_type: LogType,
level: LogLevel,
flags: LogFlags,
activity_id: Option<Guid>,
related_activity_id: Option<Guid>,
correlation_id: Option<Guid>,
name: Option<&[u8]>,
target: Option<&[u8]>,
fields: Option<&[u8]>,
message: &[u8],
timestamp: u64,
) -> Vec<u8> {
let name = name.map_or(&[] as &[u8], |slice| {
truncate_slice(slice, TRACE_LOGGING_NAME_MAX_SIZE)
});
let name_size = name.len();
let name_offset = 0;
let target = target.map_or(&[] as &[u8], |slice| {
truncate_slice(slice, TRACE_LOGGING_TARGET_MAX_SIZE)
});
let target_size = target.len();
let target_offset = name_offset + name_size;
let fields = fields.map_or(&[] as &[u8], |slice| {
truncate_slice(slice, TRACE_LOGGING_FIELDS_MAX_SIZE)
});
let fields_size = fields.len();
let fields_offset = target_offset + target_size;
let message = truncate_slice(message, TRACE_LOGGING_MESSAGE_MAX_SIZE);
let message_size = message.len();
let message_offset = fields_offset + fields_size;
let mut buffer = vec![];
let header = TraceLoggingNotificationHeader {
log_type,
level: level.into(),
flags,
name: TraceLoggingBufferOffset {
size: name_size as u16,
offset: name_offset as u16,
},
target: TraceLoggingBufferOffset {
size: target_size as u16,
offset: target_offset as u16,
},
fields: TraceLoggingBufferOffset {
size: fields_size as u16,
offset: fields_offset as u16,
},
message: TraceLoggingBufferOffset {
size: message_size as u16,
offset: message_offset as u16,
},
mbz0: 0,
activity_id: activity_id.unwrap_or(Guid::ZERO),
related_activity_id: related_activity_id.unwrap_or(Guid::ZERO),
correlation_id: correlation_id.unwrap_or(Guid::ZERO),
timestamp,
};
buffer.extend_from_slice(header.as_bytes());
buffer.extend_from_slice(name);
buffer.extend_from_slice(target);
buffer.extend_from_slice(fields);
buffer.extend_from_slice(message);
buffer
}