sessiond: return raw pointer to packet header
[lttng-tools.git] / src / bin / lttng-sessiond / field.hpp
CommitLineData
0220be14
JG
1/*
2 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#ifndef LTTNG_FIELD_H
9#define LTTNG_FIELD_H
10
0220be14
JG
11#include <memory>
12#include <string>
13#include <type_traits>
14#include <vector>
15
16#include <vendor/optional.hpp>
17
18namespace lttng {
19namespace sessiond {
20namespace trace {
21
22class field_visitor;
23class type_visitor;
24
24ed18f2
JG
25enum class byte_order {
26 BIG_ENDIAN_,
27 LITTLE_ENDIAN_,
28};
29
0220be14
JG
30/*
31 * Field, and the various field types, represents fields as exposed by the
32 * LTTng tracers. These classes do not attempt to describe the complete spectrum of the CTF
33 * specification.
34 */
35
36class type {
37public:
38 using cuptr = std::unique_ptr<const type>;
39
40 static byte_order reverse_byte_order(byte_order byte_order) noexcept;
41
42 bool operator==(const type& other) const noexcept;
43 bool operator!=(const type& other) const noexcept;
44 virtual ~type();
45 virtual void accept(type_visitor& visitor) const = 0;
46
47 const unsigned int alignment;
48
49protected:
50 type(unsigned int alignment);
51
52private:
53 virtual bool _is_equal(const type& rhs) const noexcept = 0;
54};
55
56class field {
57public:
58 using cuptr = std::unique_ptr<const field>;
59
60 field(std::string name, type::cuptr type);
61 void accept(field_visitor& visitor) const;
62 bool operator==(const field& other) const noexcept;
63
64 const std::string name;
65 const type::cuptr _type;
66};
67
68class integer_type : public type {
69public:
70 enum class signedness {
71 SIGNED,
72 UNSIGNED,
73 };
74
75 enum class base {
76 BINARY = 2,
77 OCTAL = 8,
78 DECIMAL = 10,
79 HEXADECIMAL = 16,
80 };
81
e7360180
JG
82 enum class role {
83 DEFAULT_CLOCK_TIMESTAMP,
84 /* Packet header field class specific roles. */
85 DATA_STREAM_CLASS_ID,
86 DATA_STREAM_ID,
87 PACKET_MAGIC_NUMBER,
88 /* Packet context field class specific roles. */
89 DISCARDED_EVENT_RECORD_COUNTER_SNAPSHOT,
90 PACKET_CONTENT_LENGTH,
91 PACKET_END_DEFAULT_CLOCK_TIMESTAMP,
92 PACKET_SEQUENCE_NUMBER,
93 PACKET_TOTAL_LENGTH,
94 /* Event record field class roles. */
95 EVENT_RECORD_CLASS_ID,
96 };
97
98 using roles = std::vector<role>;
99
0220be14
JG
100 integer_type(unsigned int alignment,
101 byte_order byte_order,
102 unsigned int size,
103 signedness signedness,
e7360180
JG
104 base base,
105 roles roles = {});
0220be14
JG
106
107 virtual void accept(type_visitor& visitor) const override;
108
109 const enum byte_order byte_order;
110 const unsigned int size;
65cd3c0c
JG
111 /*
112 * signedness and base are suffixed with '_' to work-around a bug in older
113 * GCCs (before 6) that do not recognize hidden/shadowed enumeration as valid
114 * nested-name-specifiers.
115 */
116 const signedness signedness_;
117 const base base_;
e7360180 118 const roles roles_;
0220be14
JG
119
120protected:
121 virtual bool _is_equal(const type& other) const noexcept override;
122};
123
124class floating_point_type : public type {
125public:
126 floating_point_type(unsigned int alignment,
127 byte_order byte_order,
128 unsigned int exponent_digits,
129 unsigned int mantissa_digits);
130
131 virtual void accept(type_visitor& visitor) const override final;
132
133 const enum byte_order byte_order;
134 const unsigned int exponent_digits;
135 const unsigned int mantissa_digits;
136
137private:
138 virtual bool _is_equal(const type& other) const noexcept override final;
139};
140
141class enumeration_type : public integer_type {
142protected:
143 enumeration_type(unsigned int alignment,
144 enum byte_order byte_order,
145 unsigned int size,
146 enum signedness signedness,
e7360180
JG
147 enum base base,
148 integer_type::roles roles = {});
0220be14
JG
149
150 virtual void accept(type_visitor& visitor) const = 0;
151};
152
153namespace details {
154template <class MappingIntegerType>
155class enumeration_mapping_range {
156public:
157 using range_integer_t = MappingIntegerType;
158
159 enumeration_mapping_range(MappingIntegerType in_begin, MappingIntegerType in_end) :
160 begin{in_begin}, end{in_end}
161 {
162 }
163
164 const range_integer_t begin, end;
165};
166
167template <class MappingIntegerType>
168bool operator==(const enumeration_mapping_range<MappingIntegerType>& lhs,
169 const enumeration_mapping_range<MappingIntegerType>& rhs) noexcept
170{
171 return lhs.begin == rhs.begin && lhs.end == rhs.end;
172}
173
174template <class MappingIntegerType>
175class enumeration_mapping {
176public:
177 using range_t = enumeration_mapping_range<MappingIntegerType>;
178
179 enumeration_mapping(const enumeration_mapping<MappingIntegerType>& other) = delete;
180 enumeration_mapping(const enumeration_mapping<MappingIntegerType>&& other) :
181 name{std::move(other.name)}, range{other.range}
182 {
183 }
184
185 /* Mapping with an implicit value. */
186 enumeration_mapping(std::string in_name) : name{std::move(in_name)}
187 {
188 }
189
190 enumeration_mapping(std::string in_name, range_t in_range) : name{std::move(in_name)}, range{in_range}
191 {
192 }
193
194 const std::string name;
195 const nonstd::optional<range_t> range;
196};
197
198template <class MappingIntegerType>
199bool operator==(const enumeration_mapping<MappingIntegerType>& lhs,
200 const enumeration_mapping<MappingIntegerType>& rhs) noexcept
201{
202 return lhs.name == rhs.name && lhs.range == rhs.range;
203}
204} /* namespace details */
205
206template <class MappingIntegerType>
207class typed_enumeration_type : public enumeration_type {
208public:
209 using mapping = details::enumeration_mapping<MappingIntegerType>;
210 using mappings = std::vector<mapping>;
211
212 static_assert(std::is_integral<MappingIntegerType>::value &&
213 sizeof(MappingIntegerType) == 8,
214 "MappingIntegerType must be either int64_t or uint64_t");
215
216 typed_enumeration_type(unsigned int in_alignment,
217 enum byte_order in_byte_order,
218 unsigned int in_size,
0220be14 219 enum base in_base,
e7360180
JG
220 const std::shared_ptr<const mappings>& in_mappings,
221 integer_type::roles in_roles = {}) :
0220be14
JG
222 enumeration_type(in_alignment,
223 in_byte_order,
224 in_size,
e7360180
JG
225 std::is_signed<MappingIntegerType>::value ?
226 integer_type::signedness::SIGNED :
227 integer_type::signedness::UNSIGNED,
228 in_base,
229 std::move(in_roles)),
0220be14
JG
230 _mappings{std::move(in_mappings)}
231 {
232 }
233
234 virtual void accept(type_visitor& visitor) const override final;
235
236 const std::shared_ptr<const mappings> _mappings;
237
238private:
239 virtual bool _is_equal(const type& base_other) const noexcept override final
240 {
241 const auto& other = static_cast<const typed_enumeration_type<MappingIntegerType>&>(
242 base_other);
243
244 return integer_type::_is_equal(base_other) && *this->_mappings == *other._mappings;
245 }
246};
247
248/* Aliases for all allowed enumeration mapping types. */
249using signed_enumeration_type = typed_enumeration_type<int64_t>;
250using unsigned_enumeration_type = typed_enumeration_type<uint64_t>;
251
252class array_type : public type {
253public:
254 array_type(unsigned int alignment, type::cuptr element_type);
255
d7bfb9b0 256 const type::cuptr element_type;
0220be14
JG
257
258protected:
259 virtual bool _is_equal(const type& base_other) const noexcept override;
260};
261
262class static_length_array_type : public array_type {
263public:
264 static_length_array_type(unsigned int alignment,
265 type::cuptr element_type,
266 uint64_t in_length);
267
268 virtual void accept(type_visitor& visitor) const override final;
269
270 const uint64_t length;
271
272private:
273 virtual bool _is_equal(const type& base_other) const noexcept override final;
274};
275
276class dynamic_length_array_type : public array_type {
277public:
278 dynamic_length_array_type(unsigned int alignment,
279 type::cuptr element_type,
280 std::string length_field_name);
281
282 virtual void accept(type_visitor& visitor) const override final;
283
284 const std::string length_field_name;
285
286private:
287 virtual bool _is_equal(const type& base_other) const noexcept override final;
288};
289
e7360180
JG
290class static_length_blob_type : public type {
291public:
292 enum class role {
293 /* Packet header field class specific role. */
294 TRACE_CLASS_UUID,
295 };
296
297 using roles = std::vector<role>;
298
299 static_length_blob_type(unsigned int alignment, uint64_t in_length_bytes, roles roles = {});
300
301 virtual void accept(type_visitor& visitor) const override final;
302
303 const uint64_t length_bytes;
304 const roles roles_;
305
306private:
307 virtual bool _is_equal(const type& base_other) const noexcept override final;
308};
309
310class dynamic_length_blob_type : public type {
311public:
312 dynamic_length_blob_type(unsigned int alignment, std::string length_field_name);
313
314 virtual void accept(type_visitor& visitor) const override final;
315
316 const std::string length_field_name;
317
318private:
319 virtual bool _is_equal(const type& base_other) const noexcept override final;
320};
321
0220be14
JG
322class string_type : public type {
323public:
324 enum class encoding {
325 ASCII,
326 UTF8,
327 };
328
329 string_type(unsigned int alignment, enum encoding encoding);
330
65cd3c0c
JG
331 /*
332 * encoding is suffixed with '_' to work-around a bug in older
333 * GCCs (before 6) that do not recognize hidden/shadowed enumeration as valid
334 * nested-name-specifiers.
335 */
336 const encoding encoding_;
0220be14
JG
337
338protected:
339 virtual bool _is_equal(const type& base_other) const noexcept override;
340};
341
342class static_length_string_type : public string_type {
343public:
344 static_length_string_type(
345 unsigned int alignment, enum encoding in_encoding, uint64_t length);
346 virtual void accept(type_visitor& visitor) const override final;
347
348 const uint64_t length;
349
350private:
351 virtual bool _is_equal(const type& base_other) const noexcept override final;
352};
353
354class dynamic_length_string_type : public string_type {
355public:
356 dynamic_length_string_type(unsigned int alignment,
357 enum encoding in_encoding,
358 std::string length_field_name);
359 virtual void accept(type_visitor& visitor) const override final;
360
361 const std::string length_field_name;
362
363private:
364 virtual bool _is_equal(const type& base_other) const noexcept override final;
365};
366
367class null_terminated_string_type : public string_type {
368public:
369 null_terminated_string_type(unsigned int alignment, enum encoding in_encoding);
370 virtual void accept(type_visitor& visitor) const override final;
371};
372
373class structure_type : public type {
374public:
375 using fields = std::vector<field::cuptr>;
376
377 structure_type(unsigned int alignment, fields in_fields);
378
379 virtual void accept(type_visitor& visitor) const override final;
380
381 const fields _fields;
382
383private:
384 virtual bool _is_equal(const type& base_other) const noexcept override final;
385};
386
387class variant_type : public type {
388public:
389 using choices = std::vector<field::cuptr>;
390
391 variant_type(unsigned int alignment, std::string tag_name, choices in_choices);
392
393 virtual void accept(type_visitor& visitor) const override final;
394
395 const std::string tag_name;
396 const choices _choices;
397
398private:
399 virtual bool _is_equal(const type& base_other) const noexcept override final;
400};
401
402class field_visitor {
403public:
404 virtual ~field_visitor() = default;
405 virtual void visit(const field& field) = 0;
406
407protected:
408 field_visitor() = default;
409};
410
411class type_visitor {
412public:
413 virtual ~type_visitor() = default;
414 virtual void visit(const integer_type& type) = 0;
415 virtual void visit(const floating_point_type& type) = 0;
416 virtual void visit(const signed_enumeration_type& type) = 0;
417 virtual void visit(const unsigned_enumeration_type& type) = 0;
418 virtual void visit(const static_length_array_type& type) = 0;
419 virtual void visit(const dynamic_length_array_type& type) = 0;
e7360180
JG
420 virtual void visit(const static_length_blob_type& type) = 0;
421 virtual void visit(const dynamic_length_blob_type& type) = 0;
0220be14
JG
422 virtual void visit(const null_terminated_string_type& type) = 0;
423 virtual void visit(const static_length_string_type& type) = 0;
424 virtual void visit(const dynamic_length_string_type& type) = 0;
425 virtual void visit(const structure_type& type) = 0;
426 virtual void visit(const variant_type& type) = 0;
427
428protected:
429 type_visitor() = default;
430};
431
432} /* namespace trace */
433} /* namespace sessiond */
434} /* namespace lttng */
435
436#endif /* LTTNG_FIELD_H */
This page took 0.040836 seconds and 4 git commands to generate.