1#![forbid(unsafe_code)]
7
8use get_protocol::LogFlags;
9use get_protocol::LogLevel;
10use get_protocol::LogType;
11use get_protocol::TRACE_LOGGING_FIELDS_MAX_SIZE;
12use get_protocol::TRACE_LOGGING_MESSAGE_MAX_SIZE;
13use get_protocol::TRACE_LOGGING_NAME_MAX_SIZE;
14use get_protocol::TRACE_LOGGING_TARGET_MAX_SIZE;
15use get_protocol::TraceLoggingBufferOffset;
16use get_protocol::TraceLoggingNotificationHeader;
17use guid::Guid;
18use zerocopy::IntoBytes;
19
20fn truncate_slice(input: &[u8], len: usize) -> &[u8] {
22 if input.len() <= len {
23 input
24 } else {
25 &input[..len]
26 }
27}
28
29pub fn build_tracelogging_notification_buffer(
31 log_type: LogType,
32 level: LogLevel,
33 flags: LogFlags,
34 activity_id: Option<Guid>,
35 related_activity_id: Option<Guid>,
36 correlation_id: Option<Guid>,
37 name: Option<&[u8]>,
38 target: Option<&[u8]>,
39 fields: Option<&[u8]>,
40 message: &[u8],
41 timestamp: u64,
42) -> Vec<u8> {
43 let name = name.map_or(&[] as &[u8], |slice| {
44 truncate_slice(slice, TRACE_LOGGING_NAME_MAX_SIZE)
45 });
46 let name_size = name.len();
47 let name_offset = 0;
48
49 let target = target.map_or(&[] as &[u8], |slice| {
50 truncate_slice(slice, TRACE_LOGGING_TARGET_MAX_SIZE)
51 });
52 let target_size = target.len();
53 let target_offset = name_offset + name_size;
54
55 let fields = fields.map_or(&[] as &[u8], |slice| {
56 truncate_slice(slice, TRACE_LOGGING_FIELDS_MAX_SIZE)
57 });
58 let fields_size = fields.len();
59 let fields_offset = target_offset + target_size;
60
61 let message = truncate_slice(message, TRACE_LOGGING_MESSAGE_MAX_SIZE);
62 let message_size = message.len();
63 let message_offset = fields_offset + fields_size;
64
65 let mut buffer = vec![];
66
67 let header = TraceLoggingNotificationHeader {
68 log_type,
69 level: level.into(),
70 flags,
71 name: TraceLoggingBufferOffset {
72 size: name_size as u16,
73 offset: name_offset as u16,
74 },
75 target: TraceLoggingBufferOffset {
76 size: target_size as u16,
77 offset: target_offset as u16,
78 },
79 fields: TraceLoggingBufferOffset {
80 size: fields_size as u16,
81 offset: fields_offset as u16,
82 },
83 message: TraceLoggingBufferOffset {
84 size: message_size as u16,
85 offset: message_offset as u16,
86 },
87 mbz0: 0,
88 activity_id: activity_id.unwrap_or(Guid::ZERO),
89 related_activity_id: related_activity_id.unwrap_or(Guid::ZERO),
90 correlation_id: correlation_id.unwrap_or(Guid::ZERO),
91 timestamp,
92 };
93
94 buffer.extend_from_slice(header.as_bytes());
95 buffer.extend_from_slice(name);
96 buffer.extend_from_slice(target);
97 buffer.extend_from_slice(fields);
98 buffer.extend_from_slice(message);
99
100 buffer
101}