Run clang-format on the whole tree
[lttng-tools.git] / src / bin / lttng-sessiond / field.cpp
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 #include "field.hpp"
9
10 #include <common/exception.hpp>
11 #include <common/format.hpp>
12
13 #include <set>
14
15 namespace lst = lttng::sessiond::trace;
16
17 namespace {
18 template <class FieldTypeSet>
19 bool fields_are_equal(const FieldTypeSet& a, const FieldTypeSet& b)
20 {
21 if (a.size() != b.size()) {
22 return false;
23 }
24
25 return std::equal(a.cbegin(),
26 a.cend(),
27 b.cbegin(),
28 [](typename FieldTypeSet::const_reference field_a,
29 typename FieldTypeSet::const_reference field_b) {
30 return *field_a == *field_b;
31 });
32 }
33 } /* namespace */
34
35 lst::field_location::field_location(lst::field_location::root in_lookup_root,
36 lst::field_location::elements in_elements) :
37 root_{ in_lookup_root }, elements_{ std::move(in_elements) }
38 {
39 }
40
41 bool lst::field_location::operator==(const lst::field_location& other) const noexcept
42 {
43 return root_ == other.root_ && elements_ == other.elements_;
44 }
45
46 lst::type::type(unsigned int in_alignment) : alignment{ in_alignment }
47 {
48 }
49
50 lst::type::~type()
51 {
52 }
53
54 bool lst::type::operator==(const lst::type& other) const noexcept
55 {
56 return typeid(*this) == typeid(other) && alignment == other.alignment &&
57 /* defer to concrete type comparison */
58 this->_is_equal(other);
59 }
60
61 bool lst::type::operator!=(const lst::type& other) const noexcept
62 {
63 return !(*this == other);
64 }
65
66 lst::field::field(std::string in_name, lst::type::cuptr in_type) :
67 name{ std::move(in_name) }, _type{ std::move(in_type) }
68 {
69 if (!_type) {
70 LTTNG_THROW_ERROR(
71 fmt::format("Invalid type used to create field: field name = `{}`", name));
72 }
73 }
74
75 void lst::field::accept(lst::field_visitor& visitor) const
76 {
77 visitor.visit(*this);
78 }
79
80 bool lst::field::operator==(const lst::field& other) const noexcept
81 {
82 return name == other.name && *_type == *other._type;
83 }
84
85 lst::type::cuptr lst::field::move_type() noexcept
86 {
87 return std::move(_type);
88 }
89
90 const lst::type& lst::field::get_type() const
91 {
92 if (_type) {
93 return *_type;
94 } else {
95 LTTNG_THROW_ERROR(fmt::format(
96 "Invalid attempt to access field type after transfer: field name = `{}`",
97 name));
98 }
99 }
100
101 lst::integer_type::integer_type(unsigned int in_alignment,
102 enum lst::byte_order in_byte_order,
103 unsigned int in_size,
104 enum lst::integer_type::signedness in_signedness,
105 enum lst::integer_type::base in_base,
106 roles in_roles) :
107 type(in_alignment),
108 byte_order{ in_byte_order },
109 size{ in_size },
110 signedness_{ in_signedness },
111 base_{ in_base },
112 roles_{ std::move(in_roles) }
113 {
114 }
115
116 lst::type::cuptr lst::integer_type::copy() const
117 {
118 return lttng::make_unique<integer_type>(
119 alignment, byte_order, size, signedness_, base_, roles_);
120 }
121
122 bool lst::integer_type::_is_equal(const type& base_other) const noexcept
123 {
124 const auto& other = static_cast<decltype(*this)&>(base_other);
125
126 return this->byte_order == other.byte_order && this->size == other.size &&
127 this->signedness_ == other.signedness_ && this->base_ == other.base_ &&
128 this->roles_ == other.roles_;
129 }
130
131 void lst::integer_type::accept(type_visitor& visitor) const
132 {
133 visitor.visit(*this);
134 }
135
136 lst::byte_order lst::type::reverse_byte_order(lst::byte_order byte_order) noexcept
137 {
138 if (byte_order == lst::byte_order::BIG_ENDIAN_) {
139 return lst::byte_order::LITTLE_ENDIAN_;
140 } else {
141 return lst::byte_order::BIG_ENDIAN_;
142 }
143 }
144
145 lst::floating_point_type::floating_point_type(unsigned int in_alignment,
146 lst::byte_order in_byte_order,
147 unsigned int in_exponent_digits,
148 unsigned int in_mantissa_digits) :
149 type(in_alignment),
150 byte_order(in_byte_order),
151 exponent_digits{ in_exponent_digits },
152 mantissa_digits(in_mantissa_digits)
153 {
154 /* Allowed (exponent, mantissa) pairs. */
155 static const std::set<std::pair<unsigned int, unsigned int>> allowed_pairs{
156 { 5, 11 }, /* binary16 */
157 { 8, 24 }, /* binary32 */
158 { 11, 53 }, /* binary64 */
159 { 15, 113 }, /* binary128 */
160 };
161
162 if (allowed_pairs.find({ exponent_digits, mantissa_digits }) != allowed_pairs.end()) {
163 /* mantissa and exponent digits is a valid pair. */
164 return;
165 }
166
167 LTTNG_THROW_INVALID_ARGUMENT_ERROR(fmt::format(
168 "Invalid exponent/mantissa values provided while creating {}", typeid(*this)));
169 }
170
171 lst::type::cuptr lst::floating_point_type::copy() const
172 {
173 return lttng::make_unique<floating_point_type>(
174 alignment, byte_order, exponent_digits, mantissa_digits);
175 }
176
177 void lst::floating_point_type::accept(type_visitor& visitor) const
178 {
179 visitor.visit(*this);
180 }
181
182 bool lst::floating_point_type::_is_equal(const type& base_other) const noexcept
183 {
184 const auto& other = static_cast<decltype(*this)&>(base_other);
185
186 return this->byte_order == other.byte_order &&
187 this->exponent_digits == other.exponent_digits &&
188 this->mantissa_digits == other.mantissa_digits;
189 }
190
191 lst::enumeration_type::enumeration_type(unsigned int in_alignment,
192 enum lst::byte_order in_byte_order,
193 unsigned int in_size,
194 enum signedness in_signedness,
195 enum base in_base,
196 lst::integer_type::roles in_roles) :
197 integer_type(
198 in_alignment, in_byte_order, in_size, in_signedness, in_base, std::move(in_roles))
199 {
200 }
201
202 /*
203 * Due to a bug in g++ < 7.1, these specializations must be enclosed in the namespaces
204 * rather than using the usual `namespace::namespace::function` notation:
205 * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
206 */
207 namespace lttng {
208 namespace sessiond {
209 namespace trace {
210 template <>
211 void signed_enumeration_type::accept(type_visitor& visitor) const
212 {
213 visitor.visit(*this);
214 }
215
216 template <>
217 void unsigned_enumeration_type::accept(type_visitor& visitor) const
218 {
219 visitor.visit(*this);
220 }
221
222 template <>
223 void variant_type<lst::signed_enumeration_type::mapping::range_t::range_integer_t>::accept(
224 lst::type_visitor& visitor) const
225 {
226 visitor.visit(*this);
227 }
228
229 template <>
230 void variant_type<lst::unsigned_enumeration_type::mapping::range_t::range_integer_t>::accept(
231 lst::type_visitor& visitor) const
232 {
233 visitor.visit(*this);
234 }
235 } /* namespace trace */
236 } /* namespace sessiond */
237 } /* namespace lttng */
238
239 lst::array_type::array_type(unsigned int in_alignment, type::cuptr in_element_type) :
240 type(in_alignment), element_type{ std::move(in_element_type) }
241 {
242 }
243
244 bool lst::array_type::_is_equal(const type& base_other) const noexcept
245 {
246 const auto& other = static_cast<decltype(*this)&>(base_other);
247
248 return *this->element_type == *other.element_type;
249 }
250
251 lst::static_length_array_type::static_length_array_type(unsigned int in_alignment,
252 type::cuptr in_element_type,
253 uint64_t in_length) :
254 array_type(in_alignment, std::move(in_element_type)), length{ in_length }
255 {
256 }
257
258 bool lst::static_length_array_type::_is_equal(const type& base_other) const noexcept
259 {
260 const auto& other = static_cast<decltype(*this)&>(base_other);
261
262 return array_type::_is_equal(base_other) && this->length == other.length;
263 }
264
265 lst::type::cuptr lst::static_length_array_type::copy() const
266 {
267 return lttng::make_unique<static_length_array_type>(
268 alignment, element_type->copy(), length);
269 }
270
271 void lst::static_length_array_type::accept(type_visitor& visitor) const
272 {
273 visitor.visit(*this);
274 }
275
276 lst::dynamic_length_array_type::dynamic_length_array_type(
277 unsigned int in_alignment,
278 type::cuptr in_element_type,
279 lst::field_location in_length_field_location) :
280 array_type(in_alignment, std::move(in_element_type)),
281 length_field_location{ std::move(in_length_field_location) }
282 {
283 }
284
285 bool lst::dynamic_length_array_type::_is_equal(const type& base_other) const noexcept
286 {
287 const auto& other = static_cast<decltype(*this)&>(base_other);
288
289 return array_type::_is_equal(base_other) &&
290 this->length_field_location == other.length_field_location;
291 }
292
293 lst::type::cuptr lst::dynamic_length_array_type::copy() const
294 {
295 return lttng::make_unique<dynamic_length_array_type>(
296 alignment, element_type->copy(), length_field_location);
297 }
298
299 void lst::dynamic_length_array_type::accept(type_visitor& visitor) const
300 {
301 visitor.visit(*this);
302 }
303
304 lst::static_length_blob_type::static_length_blob_type(unsigned int in_alignment,
305 uint64_t in_length_bytes,
306 roles in_roles) :
307 type(in_alignment), length_bytes{ in_length_bytes }, roles_{ std::move(in_roles) }
308 {
309 }
310
311 bool lst::static_length_blob_type::_is_equal(const type& base_other) const noexcept
312 {
313 const auto& other = static_cast<decltype(*this)&>(base_other);
314
315 return length_bytes == other.length_bytes && roles_ == other.roles_;
316 }
317
318 lst::type::cuptr lst::static_length_blob_type::copy() const
319 {
320 return lttng::make_unique<static_length_blob_type>(alignment, length_bytes, roles_);
321 }
322
323 void lst::static_length_blob_type::accept(type_visitor& visitor) const
324 {
325 visitor.visit(*this);
326 }
327
328 lst::dynamic_length_blob_type::dynamic_length_blob_type(
329 unsigned int in_alignment, lst::field_location in_length_field_location) :
330 type(in_alignment), length_field_location{ std::move(in_length_field_location) }
331 {
332 }
333
334 bool lst::dynamic_length_blob_type::_is_equal(const type& base_other) const noexcept
335 {
336 const auto& other = dynamic_cast<decltype(*this)&>(base_other);
337
338 return length_field_location == other.length_field_location;
339 }
340
341 lst::type::cuptr lst::dynamic_length_blob_type::copy() const
342 {
343 return lttng::make_unique<dynamic_length_blob_type>(alignment, length_field_location);
344 }
345
346 void lst::dynamic_length_blob_type::accept(type_visitor& visitor) const
347 {
348 visitor.visit(*this);
349 }
350
351 lst::string_type::string_type(unsigned int in_alignment, enum encoding in_encoding) :
352 type(in_alignment), encoding_{ in_encoding }
353 {
354 }
355
356 bool lst::string_type::_is_equal(const type& base_other) const noexcept
357 {
358 const auto& other = static_cast<decltype(*this)&>(base_other);
359
360 return this->encoding_ == other.encoding_;
361 }
362
363 lst::static_length_string_type::static_length_string_type(unsigned int in_alignment,
364 enum encoding in_encoding,
365 uint64_t in_length) :
366 string_type(in_alignment, in_encoding), length{ in_length }
367 {
368 }
369
370 bool lst::static_length_string_type::_is_equal(const type& base_other) const noexcept
371 {
372 const auto& other = static_cast<decltype(*this)&>(base_other);
373
374 return string_type::_is_equal(base_other) && this->length == other.length;
375 }
376
377 lst::type::cuptr lst::static_length_string_type::copy() const
378 {
379 return lttng::make_unique<static_length_string_type>(alignment, encoding_, length);
380 }
381
382 void lst::static_length_string_type::accept(type_visitor& visitor) const
383 {
384 visitor.visit(*this);
385 }
386
387 lst::dynamic_length_string_type::dynamic_length_string_type(
388 unsigned int in_alignment,
389 enum encoding in_encoding,
390 field_location in_length_field_location) :
391 string_type(in_alignment, in_encoding),
392 length_field_location{ std::move(in_length_field_location) }
393 {
394 }
395
396 bool lst::dynamic_length_string_type::_is_equal(const type& base_other) const noexcept
397 {
398 const auto& other = static_cast<decltype(*this)&>(base_other);
399
400 return string_type::_is_equal(base_other) &&
401 this->length_field_location == other.length_field_location;
402 }
403
404 lst::type::cuptr lst::dynamic_length_string_type::copy() const
405 {
406 return lttng::make_unique<dynamic_length_string_type>(
407 alignment, encoding_, length_field_location);
408 }
409
410 void lst::dynamic_length_string_type::accept(type_visitor& visitor) const
411 {
412 visitor.visit(*this);
413 }
414
415 lst::null_terminated_string_type::null_terminated_string_type(unsigned int in_alignment,
416 enum encoding in_encoding) :
417 string_type(in_alignment, in_encoding)
418 {
419 }
420
421 lst::type::cuptr lst::null_terminated_string_type::copy() const
422 {
423 return lttng::make_unique<null_terminated_string_type>(alignment, encoding_);
424 }
425
426 void lst::null_terminated_string_type::accept(type_visitor& visitor) const
427 {
428 visitor.visit(*this);
429 }
430
431 lst::structure_type::structure_type(unsigned int in_alignment, fields in_fields) :
432 type(in_alignment), fields_{ std::move(in_fields) }
433 {
434 }
435
436 bool lst::structure_type::_is_equal(const type& base_other) const noexcept
437 {
438 const auto& other = static_cast<decltype(*this)&>(base_other);
439
440 return fields_are_equal(this->fields_, other.fields_);
441 }
442
443 lst::type::cuptr lst::structure_type::copy() const
444 {
445 structure_type::fields copy_of_fields;
446
447 copy_of_fields.reserve(fields_.size());
448 for (const auto& field : fields_) {
449 copy_of_fields.emplace_back(
450 lttng::make_unique<lst::field>(field->name, field->get_type().copy()));
451 }
452
453 return lttng::make_unique<structure_type>(alignment, std::move(copy_of_fields));
454 }
455
456 void lst::structure_type::accept(type_visitor& visitor) const
457 {
458 visitor.visit(*this);
459 }
This page took 0.038544 seconds and 5 git commands to generate.