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