2 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
10 #include <common/exception.hpp>
11 #include <common/format.hpp>
15 namespace lst
= lttng::sessiond::trace
;
18 template <class FieldTypeContainerType
>
19 bool fields_are_equal(const FieldTypeContainerType
& a
, const FieldTypeContainerType
& b
)
21 if (a
.size() != b
.size()) {
25 return std::equal(a
.cbegin(),
28 [](typename
FieldTypeContainerType::const_reference field_a
,
29 typename
FieldTypeContainerType::const_reference field_b
) {
30 return *field_a
== *field_b
;
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
) }
41 bool lst::field_location::operator==(const lst::field_location
& other
) const noexcept
43 return root_
== other
.root_
&& elements_
== other
.elements_
;
46 lst::type::type(unsigned int in_alignment
) : alignment
{ in_alignment
}
50 lst::type::~type() = default;
52 bool lst::type::operator==(const lst::type
& other
) const noexcept
54 return typeid(*this) == typeid(other
) && alignment
== other
.alignment
&&
55 /* defer to concrete type comparison */
56 this->_is_equal(other
);
59 bool lst::type::operator!=(const lst::type
& other
) const noexcept
61 return !(*this == other
);
64 lst::field::field(std::string in_name
, lst::type::cuptr in_type
) :
65 name
{ std::move(in_name
) }, _type
{ std::move(in_type
) }
69 fmt::format("Invalid type used to create field: field name = `{}`", name
));
73 void lst::field::accept(lst::field_visitor
& visitor
) const
78 bool lst::field::operator==(const lst::field
& other
) const noexcept
80 return name
== other
.name
&& *_type
== *other
._type
;
83 lst::type::cuptr
lst::field::move_type() noexcept
85 return std::move(_type
);
88 const lst::type
& lst::field::get_type() const
93 LTTNG_THROW_ERROR(fmt::format(
94 "Invalid attempt to access field type after transfer: field name = `{}`",
99 lst::integer_type::integer_type(unsigned int in_alignment
,
100 enum lst::byte_order in_byte_order
,
101 unsigned int in_size
,
102 enum lst::integer_type::signedness in_signedness
,
103 enum lst::integer_type::base in_base
,
106 byte_order
{ in_byte_order
},
108 signedness_
{ in_signedness
},
110 roles_
{ std::move(in_roles
) }
114 lst::type::cuptr
lst::integer_type::copy() const
116 return lttng::make_unique
<integer_type
>(
117 alignment
, byte_order
, size
, signedness_
, base_
, roles_
);
120 bool lst::integer_type::_is_equal(const type
& base_other
) const noexcept
122 const auto& other
= static_cast<decltype(*this)&>(base_other
);
124 return this->byte_order
== other
.byte_order
&& this->size
== other
.size
&&
125 this->signedness_
== other
.signedness_
&& this->base_
== other
.base_
&&
126 this->roles_
== other
.roles_
;
129 void lst::integer_type::accept(type_visitor
& visitor
) const
131 visitor
.visit(*this);
134 lst::byte_order
lst::type::reverse_byte_order(lst::byte_order byte_order
) noexcept
136 if (byte_order
== lst::byte_order::BIG_ENDIAN_
) {
137 return lst::byte_order::LITTLE_ENDIAN_
;
139 return lst::byte_order::BIG_ENDIAN_
;
143 lst::floating_point_type::floating_point_type(unsigned int in_alignment
,
144 lst::byte_order in_byte_order
,
145 unsigned int in_exponent_digits
,
146 unsigned int in_mantissa_digits
) :
148 byte_order(in_byte_order
),
149 exponent_digits
{ in_exponent_digits
},
150 mantissa_digits(in_mantissa_digits
)
152 /* Allowed (exponent, mantissa) pairs. */
153 static const std::set
<std::pair
<unsigned int, unsigned int>> allowed_pairs
{
154 { 5, 11 }, /* binary16 */
155 { 8, 24 }, /* binary32 */
156 { 11, 53 }, /* binary64 */
157 { 15, 113 }, /* binary128 */
160 if (allowed_pairs
.find({ exponent_digits
, mantissa_digits
}) != allowed_pairs
.end()) {
161 /* mantissa and exponent digits is a valid pair. */
165 LTTNG_THROW_INVALID_ARGUMENT_ERROR(fmt::format(
166 "Invalid exponent/mantissa values provided while creating {}", typeid(*this)));
169 lst::type::cuptr
lst::floating_point_type::copy() const
171 return lttng::make_unique
<floating_point_type
>(
172 alignment
, byte_order
, exponent_digits
, mantissa_digits
);
175 void lst::floating_point_type::accept(type_visitor
& visitor
) const
177 visitor
.visit(*this);
180 bool lst::floating_point_type::_is_equal(const type
& base_other
) const noexcept
182 const auto& other
= static_cast<decltype(*this)&>(base_other
);
184 return this->byte_order
== other
.byte_order
&&
185 this->exponent_digits
== other
.exponent_digits
&&
186 this->mantissa_digits
== other
.mantissa_digits
;
189 lst::enumeration_type::enumeration_type(unsigned int in_alignment
,
190 enum lst::byte_order in_byte_order
,
191 unsigned int in_size
,
192 enum signedness in_signedness
,
194 lst::integer_type::roles in_roles
) :
196 in_alignment
, in_byte_order
, in_size
, in_signedness
, in_base
, std::move(in_roles
))
201 * Due to a bug in g++ < 7.1, these specializations must be enclosed in the namespaces
202 * rather than using the usual `namespace::namespace::function` notation:
203 * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
209 void signed_enumeration_type::accept(type_visitor
& visitor
) const
211 visitor
.visit(*this);
215 void unsigned_enumeration_type::accept(type_visitor
& visitor
) const
217 visitor
.visit(*this);
221 void variant_type
<lst::signed_enumeration_type::mapping::range_t::range_integer_t
>::accept(
222 lst::type_visitor
& visitor
) const
224 visitor
.visit(*this);
228 void variant_type
<lst::unsigned_enumeration_type::mapping::range_t::range_integer_t
>::accept(
229 lst::type_visitor
& visitor
) const
231 visitor
.visit(*this);
233 } /* namespace trace */
234 } /* namespace sessiond */
235 } /* namespace lttng */
237 lst::array_type::array_type(unsigned int in_alignment
, type::cuptr in_element_type
) :
238 type(in_alignment
), element_type
{ std::move(in_element_type
) }
242 bool lst::array_type::_is_equal(const type
& base_other
) const noexcept
244 const auto& other
= static_cast<decltype(*this)&>(base_other
);
246 return *this->element_type
== *other
.element_type
;
249 lst::static_length_array_type::static_length_array_type(unsigned int in_alignment
,
250 type::cuptr in_element_type
,
251 uint64_t in_length
) :
252 array_type(in_alignment
, std::move(in_element_type
)), length
{ in_length
}
256 bool lst::static_length_array_type::_is_equal(const type
& base_other
) const noexcept
258 const auto& other
= static_cast<decltype(*this)&>(base_other
);
260 return array_type::_is_equal(base_other
) && this->length
== other
.length
;
263 lst::type::cuptr
lst::static_length_array_type::copy() const
265 return lttng::make_unique
<static_length_array_type
>(
266 alignment
, element_type
->copy(), length
);
269 void lst::static_length_array_type::accept(type_visitor
& visitor
) const
271 visitor
.visit(*this);
274 lst::dynamic_length_array_type::dynamic_length_array_type(
275 unsigned int in_alignment
,
276 type::cuptr in_element_type
,
277 lst::field_location in_length_field_location
) :
278 array_type(in_alignment
, std::move(in_element_type
)),
279 length_field_location
{ std::move(in_length_field_location
) }
283 bool lst::dynamic_length_array_type::_is_equal(const type
& base_other
) const noexcept
285 const auto& other
= static_cast<decltype(*this)&>(base_other
);
287 return array_type::_is_equal(base_other
) &&
288 this->length_field_location
== other
.length_field_location
;
291 lst::type::cuptr
lst::dynamic_length_array_type::copy() const
293 return lttng::make_unique
<dynamic_length_array_type
>(
294 alignment
, element_type
->copy(), length_field_location
);
297 void lst::dynamic_length_array_type::accept(type_visitor
& visitor
) const
299 visitor
.visit(*this);
302 lst::static_length_blob_type::static_length_blob_type(unsigned int in_alignment
,
303 uint64_t in_length_bytes
,
305 type(in_alignment
), length_bytes
{ in_length_bytes
}, roles_
{ std::move(in_roles
) }
309 bool lst::static_length_blob_type::_is_equal(const type
& base_other
) const noexcept
311 const auto& other
= static_cast<decltype(*this)&>(base_other
);
313 return length_bytes
== other
.length_bytes
&& roles_
== other
.roles_
;
316 lst::type::cuptr
lst::static_length_blob_type::copy() const
318 return lttng::make_unique
<static_length_blob_type
>(alignment
, length_bytes
, roles_
);
321 void lst::static_length_blob_type::accept(type_visitor
& visitor
) const
323 visitor
.visit(*this);
326 lst::dynamic_length_blob_type::dynamic_length_blob_type(
327 unsigned int in_alignment
, lst::field_location in_length_field_location
) :
328 type(in_alignment
), length_field_location
{ std::move(in_length_field_location
) }
332 bool lst::dynamic_length_blob_type::_is_equal(const type
& base_other
) const noexcept
334 const auto& other
= dynamic_cast<decltype(*this)&>(base_other
);
336 return length_field_location
== other
.length_field_location
;
339 lst::type::cuptr
lst::dynamic_length_blob_type::copy() const
341 return lttng::make_unique
<dynamic_length_blob_type
>(alignment
, length_field_location
);
344 void lst::dynamic_length_blob_type::accept(type_visitor
& visitor
) const
346 visitor
.visit(*this);
349 lst::string_type::string_type(unsigned int in_alignment
, enum encoding in_encoding
) :
350 type(in_alignment
), encoding_
{ in_encoding
}
354 bool lst::string_type::_is_equal(const type
& base_other
) const noexcept
356 const auto& other
= static_cast<decltype(*this)&>(base_other
);
358 return this->encoding_
== other
.encoding_
;
361 lst::static_length_string_type::static_length_string_type(unsigned int in_alignment
,
362 enum encoding in_encoding
,
363 uint64_t in_length
) :
364 string_type(in_alignment
, in_encoding
), length
{ in_length
}
368 bool lst::static_length_string_type::_is_equal(const type
& base_other
) const noexcept
370 const auto& other
= static_cast<decltype(*this)&>(base_other
);
372 return string_type::_is_equal(base_other
) && this->length
== other
.length
;
375 lst::type::cuptr
lst::static_length_string_type::copy() const
377 return lttng::make_unique
<static_length_string_type
>(alignment
, encoding_
, length
);
380 void lst::static_length_string_type::accept(type_visitor
& visitor
) const
382 visitor
.visit(*this);
385 lst::dynamic_length_string_type::dynamic_length_string_type(
386 unsigned int in_alignment
,
387 enum encoding in_encoding
,
388 field_location in_length_field_location
) :
389 string_type(in_alignment
, in_encoding
),
390 length_field_location
{ std::move(in_length_field_location
) }
394 bool lst::dynamic_length_string_type::_is_equal(const type
& base_other
) const noexcept
396 const auto& other
= static_cast<decltype(*this)&>(base_other
);
398 return string_type::_is_equal(base_other
) &&
399 this->length_field_location
== other
.length_field_location
;
402 lst::type::cuptr
lst::dynamic_length_string_type::copy() const
404 return lttng::make_unique
<dynamic_length_string_type
>(
405 alignment
, encoding_
, length_field_location
);
408 void lst::dynamic_length_string_type::accept(type_visitor
& visitor
) const
410 visitor
.visit(*this);
413 lst::null_terminated_string_type::null_terminated_string_type(unsigned int in_alignment
,
414 enum encoding in_encoding
) :
415 string_type(in_alignment
, in_encoding
)
419 lst::type::cuptr
lst::null_terminated_string_type::copy() const
421 return lttng::make_unique
<null_terminated_string_type
>(alignment
, encoding_
);
424 void lst::null_terminated_string_type::accept(type_visitor
& visitor
) const
426 visitor
.visit(*this);
429 lst::structure_type::structure_type(unsigned int in_alignment
, fields in_fields
) :
430 type(in_alignment
), fields_
{ std::move(in_fields
) }
434 bool lst::structure_type::_is_equal(const type
& base_other
) const noexcept
436 const auto& other
= static_cast<decltype(*this)&>(base_other
);
438 return fields_are_equal(this->fields_
, other
.fields_
);
441 lst::type::cuptr
lst::structure_type::copy() const
443 structure_type::fields copy_of_fields
;
445 copy_of_fields
.reserve(fields_
.size());
446 for (const auto& field
: fields_
) {
447 copy_of_fields
.emplace_back(
448 lttng::make_unique
<lst::field
>(field
->name
, field
->get_type().copy()));
451 return lttng::make_unique
<structure_type
>(alignment
, std::move(copy_of_fields
));
454 void lst::structure_type::accept(type_visitor
& visitor
) const
456 visitor
.visit(*this);