linux_perf_event_reader/
common_data.rs1use byteorder::{BigEndian, ByteOrder, LittleEndian};
2
3use crate::{Endianness, RawData, SampleFormat};
4
5use super::RecordParseInfo;
6
7#[derive(Clone, Debug, Default)]
8pub struct CommonData {
9 pub pid: Option<i32>,
10 pub tid: Option<i32>,
11 pub timestamp: Option<u64>,
12 pub id: Option<u64>,
13 pub stream_id: Option<u64>,
14 pub cpu: Option<u32>,
15}
16
17impl CommonData {
18 pub fn parse_sample(
19 data: RawData,
20 parse_info: &RecordParseInfo,
21 ) -> Result<Self, std::io::Error> {
22 match parse_info.endian {
23 Endianness::LittleEndian => Self::parse_sample_impl::<LittleEndian>(data, parse_info),
24 Endianness::BigEndian => Self::parse_sample_impl::<BigEndian>(data, parse_info),
25 }
26 }
27
28 pub fn parse_sample_impl<T: ByteOrder>(
29 data: RawData,
30 parse_info: &RecordParseInfo,
31 ) -> Result<Self, std::io::Error> {
32 let sample_format = parse_info.sample_format;
33
34 let mut cur = data;
43 let identifier = if sample_format.contains(SampleFormat::IDENTIFIER) {
44 Some(cur.read_u64::<T>()?)
45 } else {
46 None
47 };
48
49 if sample_format.contains(SampleFormat::IP) {
50 let _ip = cur.read_u64::<T>()?;
51 }
52
53 let (pid, tid) = if sample_format.contains(SampleFormat::TID) {
54 let pid = cur.read_i32::<T>()?;
55 let tid = cur.read_i32::<T>()?;
56 (Some(pid), Some(tid))
57 } else {
58 (None, None)
59 };
60
61 let timestamp = if sample_format.contains(SampleFormat::TIME) {
62 Some(cur.read_u64::<T>()?)
63 } else {
64 None
65 };
66
67 if sample_format.contains(SampleFormat::ADDR) {
68 let _addr = cur.read_u64::<T>()?;
69 }
70
71 let id = if sample_format.contains(SampleFormat::ID) {
72 Some(cur.read_u64::<T>()?)
73 } else {
74 None
75 };
76 let id = identifier.or(id);
77
78 let stream_id = if sample_format.contains(SampleFormat::STREAM_ID) {
79 Some(cur.read_u64::<T>()?)
80 } else {
81 None
82 };
83
84 let cpu = if sample_format.contains(SampleFormat::CPU) {
85 let cpu = cur.read_u32::<T>()?;
86 let _ = cur.read_u32::<T>()?; Some(cpu)
88 } else {
89 None
90 };
91
92 Ok(CommonData {
93 pid,
94 tid,
95 timestamp,
96 id,
97 stream_id,
98 cpu,
99 })
100 }
101
102 pub fn parse_nonsample(
103 data: RawData,
104 parse_info: &RecordParseInfo,
105 ) -> Result<Self, std::io::Error> {
106 match parse_info.endian {
107 Endianness::LittleEndian => {
108 Self::parse_nonsample_impl::<LittleEndian>(data, parse_info)
109 }
110 Endianness::BigEndian => Self::parse_nonsample_impl::<BigEndian>(data, parse_info),
111 }
112 }
113
114 pub fn parse_nonsample_impl<T: ByteOrder>(
115 data: RawData,
116 parse_info: &RecordParseInfo,
117 ) -> Result<Self, std::io::Error> {
118 if let Some(common_data_offset_from_end) = parse_info.common_data_offset_from_end {
119 let common_data_offset_from_end = common_data_offset_from_end as usize;
120 let sample_format = parse_info.sample_format;
121
122 let mut cur = data;
123 let common_data_offset_from_start = cur
124 .len()
125 .checked_sub(common_data_offset_from_end)
126 .ok_or(std::io::ErrorKind::UnexpectedEof)?;
127 cur.skip(common_data_offset_from_start)?;
128
129 let (pid, tid) = if sample_format.contains(SampleFormat::TID) {
138 let pid = cur.read_i32::<T>()?;
139 let tid = cur.read_i32::<T>()?;
140 (Some(pid), Some(tid))
141 } else {
142 (None, None)
143 };
144
145 let timestamp = if sample_format.contains(SampleFormat::TIME) {
146 Some(cur.read_u64::<T>()?)
147 } else {
148 None
149 };
150
151 let id = if sample_format.contains(SampleFormat::ID) {
152 Some(cur.read_u64::<T>()?)
153 } else {
154 None
155 };
156
157 let stream_id = if sample_format.contains(SampleFormat::STREAM_ID) {
158 Some(cur.read_u64::<T>()?)
159 } else {
160 None
161 };
162
163 let cpu = if sample_format.contains(SampleFormat::CPU) {
164 let cpu = cur.read_u32::<T>()?;
165 let _ = cur.read_u32::<T>()?; Some(cpu)
167 } else {
168 None
169 };
170
171 let identifier = if sample_format.contains(SampleFormat::IDENTIFIER) {
172 Some(cur.read_u64::<T>()?)
173 } else {
174 None
175 };
176 let id = identifier.or(id);
177
178 Ok(CommonData {
179 pid,
180 tid,
181 timestamp,
182 id,
183 stream_id,
184 cpu,
185 })
186 } else {
187 Ok(Default::default())
188 }
189 }
190}