sessiond: transition from lttng-ust to tracer agnostic API
[lttng-tools.git] / src / bin / lttng-sessiond / field.hpp
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
20 namespace lttng {
21 namespace sessiond {
22 namespace trace {
23
24 class field_visitor;
25 class 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
33 class type {
34 public:
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
46 protected:
47 type(unsigned int alignment);
48
49 private:
50 virtual bool _is_equal(const type& rhs) const noexcept = 0;
51 };
52
53 class field {
54 public:
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
65 class integer_type : public type {
66 public:
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
79 integer_type(unsigned int alignment,
80 byte_order byte_order,
81 unsigned int size,
82 signedness signedness,
83 base base);
84
85 virtual void accept(type_visitor& visitor) const override;
86
87 const enum byte_order byte_order;
88 const unsigned int size;
89 const signedness signedness;
90 const base base;
91
92 protected:
93 virtual bool _is_equal(const type& other) const noexcept override;
94 };
95
96 class floating_point_type : public type {
97 public:
98 floating_point_type(unsigned int alignment,
99 byte_order byte_order,
100 unsigned int exponent_digits,
101 unsigned int mantissa_digits);
102
103 virtual void accept(type_visitor& visitor) const override final;
104
105 const enum byte_order byte_order;
106 const unsigned int exponent_digits;
107 const unsigned int mantissa_digits;
108
109 private:
110 virtual bool _is_equal(const type& other) const noexcept override final;
111 };
112
113 class enumeration_type : public integer_type {
114 protected:
115 enumeration_type(unsigned int alignment,
116 enum byte_order byte_order,
117 unsigned int size,
118 enum signedness signedness,
119 enum base base);
120
121 virtual void accept(type_visitor& visitor) const = 0;
122 };
123
124 namespace details {
125 template <class MappingIntegerType>
126 class enumeration_mapping_range {
127 public:
128 using range_integer_t = MappingIntegerType;
129
130 enumeration_mapping_range(MappingIntegerType in_begin, MappingIntegerType in_end) :
131 begin{in_begin}, end{in_end}
132 {
133 }
134
135 const range_integer_t begin, end;
136 };
137
138 template <class MappingIntegerType>
139 bool operator==(const enumeration_mapping_range<MappingIntegerType>& lhs,
140 const enumeration_mapping_range<MappingIntegerType>& rhs) noexcept
141 {
142 return lhs.begin == rhs.begin && lhs.end == rhs.end;
143 }
144
145 template <class MappingIntegerType>
146 class enumeration_mapping {
147 public:
148 using range_t = enumeration_mapping_range<MappingIntegerType>;
149
150 enumeration_mapping(const enumeration_mapping<MappingIntegerType>& other) = delete;
151 enumeration_mapping(const enumeration_mapping<MappingIntegerType>&& other) :
152 name{std::move(other.name)}, range{other.range}
153 {
154 }
155
156 /* Mapping with an implicit value. */
157 enumeration_mapping(std::string in_name) : name{std::move(in_name)}
158 {
159 }
160
161 enumeration_mapping(std::string in_name, range_t in_range) : name{std::move(in_name)}, range{in_range}
162 {
163 }
164
165 const std::string name;
166 const nonstd::optional<range_t> range;
167 };
168
169 template <class MappingIntegerType>
170 bool operator==(const enumeration_mapping<MappingIntegerType>& lhs,
171 const enumeration_mapping<MappingIntegerType>& rhs) noexcept
172 {
173 return lhs.name == rhs.name && lhs.range == rhs.range;
174 }
175 } /* namespace details */
176
177 template <class MappingIntegerType>
178 class typed_enumeration_type : public enumeration_type {
179 public:
180 using mapping = details::enumeration_mapping<MappingIntegerType>;
181 using mappings = std::vector<mapping>;
182
183 static_assert(std::is_integral<MappingIntegerType>::value &&
184 sizeof(MappingIntegerType) == 8,
185 "MappingIntegerType must be either int64_t or uint64_t");
186
187 typed_enumeration_type(unsigned int in_alignment,
188 enum byte_order in_byte_order,
189 unsigned int in_size,
190 enum signedness in_signedness,
191 enum base in_base,
192 const std::shared_ptr<const mappings>& in_mappings) :
193 enumeration_type(in_alignment,
194 in_byte_order,
195 in_size,
196 in_signedness,
197 in_base),
198 _mappings{std::move(in_mappings)}
199 {
200 }
201
202 virtual void accept(type_visitor& visitor) const override final;
203
204 const std::shared_ptr<const mappings> _mappings;
205
206 private:
207 virtual bool _is_equal(const type& base_other) const noexcept override final
208 {
209 const auto& other = static_cast<const typed_enumeration_type<MappingIntegerType>&>(
210 base_other);
211
212 return integer_type::_is_equal(base_other) && *this->_mappings == *other._mappings;
213 }
214 };
215
216 /* Aliases for all allowed enumeration mapping types. */
217 using signed_enumeration_type = typed_enumeration_type<int64_t>;
218 using unsigned_enumeration_type = typed_enumeration_type<uint64_t>;
219
220 class array_type : public type {
221 public:
222 array_type(unsigned int alignment, type::cuptr element_type);
223
224 const type::cuptr element_type;
225
226 protected:
227 virtual bool _is_equal(const type& base_other) const noexcept override;
228 };
229
230 class static_length_array_type : public array_type {
231 public:
232 static_length_array_type(unsigned int alignment,
233 type::cuptr element_type,
234 uint64_t in_length);
235
236 virtual void accept(type_visitor& visitor) const override final;
237
238 const uint64_t length;
239
240 private:
241 virtual bool _is_equal(const type& base_other) const noexcept override final;
242 };
243
244 class dynamic_length_array_type : public array_type {
245 public:
246 dynamic_length_array_type(unsigned int alignment,
247 type::cuptr element_type,
248 std::string length_field_name);
249
250 virtual void accept(type_visitor& visitor) const override final;
251
252 const std::string length_field_name;
253
254 private:
255 virtual bool _is_equal(const type& base_other) const noexcept override final;
256 };
257
258 class string_type : public type {
259 public:
260 enum class encoding {
261 ASCII,
262 UTF8,
263 };
264
265 string_type(unsigned int alignment, enum encoding encoding);
266
267 const encoding encoding;
268
269 protected:
270 virtual bool _is_equal(const type& base_other) const noexcept override;
271 };
272
273 class static_length_string_type : public string_type {
274 public:
275 static_length_string_type(
276 unsigned int alignment, enum encoding in_encoding, uint64_t length);
277 virtual void accept(type_visitor& visitor) const override final;
278
279 const uint64_t length;
280
281 private:
282 virtual bool _is_equal(const type& base_other) const noexcept override final;
283 };
284
285 class dynamic_length_string_type : public string_type {
286 public:
287 dynamic_length_string_type(unsigned int alignment,
288 enum encoding in_encoding,
289 std::string length_field_name);
290 virtual void accept(type_visitor& visitor) const override final;
291
292 const std::string length_field_name;
293
294 private:
295 virtual bool _is_equal(const type& base_other) const noexcept override final;
296 };
297
298 class null_terminated_string_type : public string_type {
299 public:
300 null_terminated_string_type(unsigned int alignment, enum encoding in_encoding);
301 virtual void accept(type_visitor& visitor) const override final;
302 };
303
304 class structure_type : public type {
305 public:
306 using fields = std::vector<field::cuptr>;
307
308 structure_type(unsigned int alignment, fields in_fields);
309
310 virtual void accept(type_visitor& visitor) const override final;
311
312 const fields _fields;
313
314 private:
315 virtual bool _is_equal(const type& base_other) const noexcept override final;
316 };
317
318 class variant_type : public type {
319 public:
320 using choices = std::vector<field::cuptr>;
321
322 variant_type(unsigned int alignment, std::string tag_name, choices in_choices);
323
324 virtual void accept(type_visitor& visitor) const override final;
325
326 const std::string tag_name;
327 const choices _choices;
328
329 private:
330 virtual bool _is_equal(const type& base_other) const noexcept override final;
331 };
332
333 class field_visitor {
334 public:
335 virtual ~field_visitor() = default;
336 virtual void visit(const field& field) = 0;
337
338 protected:
339 field_visitor() = default;
340 };
341
342 class type_visitor {
343 public:
344 virtual ~type_visitor() = default;
345 virtual void visit(const integer_type& type) = 0;
346 virtual void visit(const floating_point_type& type) = 0;
347 virtual void visit(const signed_enumeration_type& type) = 0;
348 virtual void visit(const unsigned_enumeration_type& type) = 0;
349 virtual void visit(const static_length_array_type& type) = 0;
350 virtual void visit(const dynamic_length_array_type& type) = 0;
351 virtual void visit(const null_terminated_string_type& type) = 0;
352 virtual void visit(const static_length_string_type& type) = 0;
353 virtual void visit(const dynamic_length_string_type& type) = 0;
354 virtual void visit(const structure_type& type) = 0;
355 virtual void visit(const variant_type& type) = 0;
356
357 protected:
358 type_visitor() = default;
359 };
360
361 } /* namespace trace */
362 } /* namespace sessiond */
363 } /* namespace lttng */
364
365 #endif /* LTTNG_FIELD_H */
This page took 0.036843 seconds and 4 git commands to generate.