sessiond: add tracer-agnostic trace hierarchy classes
[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 namespace lst = lttng::sessiond::trace;
14
15 namespace {
16 template <class FieldTypeSet>
17 bool fields_are_equal(const FieldTypeSet& a, const FieldTypeSet& b)
18 {
19 if (a.size() != b.size()) {
20 return false;
21 }
22
23 return std::equal(a.cbegin(), a.cend(), b.cbegin(),
24 [](typename FieldTypeSet::const_reference field_a,
25 typename FieldTypeSet::const_reference field_b) {
26 return *field_a == *field_b;
27 });
28 }
29 } /* namespace */
30
31 lst::type::type(unsigned int in_alignment) : alignment{in_alignment}
32 {
33 }
34
35 lst::type::~type()
36 {
37 }
38
39 bool lst::type::operator==(const lst::type& other) const noexcept
40 {
41 return typeid(*this) == typeid(other) &&
42 alignment == other.alignment &&
43 /* defer to concrete type comparison */
44 this->_is_equal(other);
45 }
46
47 bool lst::type::operator!=(const lst::type& other) const noexcept
48 {
49 return !(*this == other);
50 }
51
52 lst::field::field(std::string in_name, lst::type::cuptr in_type) :
53 name{std::move(in_name)}, _type{std::move(in_type)}
54 {
55 }
56
57 void lst::field::accept(lst::field_visitor& visitor) const
58 {
59 visitor.visit(*this);
60 }
61
62 bool lst::field::operator==(const lst::field& other) const noexcept
63 {
64 return name == other.name && *_type == *other._type;
65 }
66
67 lst::integer_type::integer_type(unsigned int in_alignment,
68 enum lst::byte_order in_byte_order,
69 unsigned int in_size,
70 enum lst::integer_type::signedness in_signedness,
71 enum lst::integer_type::base in_base) :
72 type(in_alignment),
73 byte_order{in_byte_order},
74 size{in_size},
75 signedness{in_signedness},
76 base{in_base}
77 {
78 }
79
80 bool lst::integer_type::_is_equal(const type &base_other) const noexcept
81 {
82 const auto& other = static_cast<decltype(*this)&>(base_other);
83
84 return this->byte_order == other.byte_order &&
85 this->size == other.size &&
86 this->signedness == other.signedness &&
87 this->base == other.base;
88 }
89
90 void lst::integer_type::accept(type_visitor& visitor) const
91 {
92 visitor.visit(*this);
93 }
94
95 lst::byte_order lst::type::reverse_byte_order(lst::byte_order byte_order) noexcept
96 {
97 if (byte_order == lst::byte_order::BIG_ENDIAN_) {
98 return lst::byte_order::LITTLE_ENDIAN_;
99 } else {
100 return lst::byte_order::BIG_ENDIAN_;
101 }
102 }
103
104 lst::floating_point_type::floating_point_type(unsigned int in_alignment,
105 lst::byte_order in_byte_order,
106 unsigned int in_exponent_digits,
107 unsigned int in_mantissa_digits) :
108 type(in_alignment),
109 byte_order(in_byte_order),
110 exponent_digits{in_exponent_digits},
111 mantissa_digits(in_mantissa_digits)
112 {
113 /* Allowed (exponent, mantissa) pairs. */
114 static const std::vector<std::pair<unsigned int, unsigned int>> allowed_pairs{
115 {5, 11}, /* binary16 */
116 {8, 24}, /* binary32 */
117 {11, 53}, /* binary64 */
118 {15, 113}, /* binary128 */
119 };
120
121 const auto input_pair = decltype(allowed_pairs)::value_type(exponent_digits, mantissa_digits);
122 for (const auto& pair : allowed_pairs) {
123 if (input_pair == pair) {
124 /* mantissa and exponent digits is a valid pair. */
125 return;
126 }
127 }
128
129 LTTNG_THROW_INVALID_ARGUMENT_ERROR(
130 fmt::format("Invalid exponent/mantissa values provided while creating {}",
131 typeid(*this)));
132 }
133
134 void lst::floating_point_type::accept(type_visitor& visitor) const
135 {
136 visitor.visit(*this);
137 }
138
139 bool lst::floating_point_type::_is_equal(const type& base_other) const noexcept
140 {
141 const auto& other = static_cast<decltype(*this)&>(base_other);
142
143 return this->byte_order == other.byte_order &&
144 this->exponent_digits == other.exponent_digits &&
145 this->mantissa_digits == other.mantissa_digits;
146 }
147
148 lst::enumeration_type::enumeration_type(unsigned int in_alignment,
149 enum lst::byte_order in_byte_order,
150 unsigned int in_size,
151 enum signedness in_signedness,
152 enum base in_base) :
153 integer_type(in_alignment, in_byte_order, in_size, in_signedness, in_base)
154 {
155 }
156
157 template <>
158 void lst::signed_enumeration_type::accept(type_visitor& visitor) const
159 {
160 visitor.visit(*this);
161 }
162
163 template <>
164 void lst::unsigned_enumeration_type::accept(type_visitor& visitor) const
165 {
166 visitor.visit(*this);
167 }
168
169 lst::array_type::array_type(unsigned int in_alignment, type::cuptr in_element_type) :
170 type(in_alignment), element_type{std::move(in_element_type)}
171 {
172 }
173
174 bool lst::array_type::_is_equal(const type& base_other) const noexcept
175 {
176 const auto& other = static_cast<decltype(*this)&>(base_other);
177
178 return *this->element_type == *other.element_type;
179 }
180
181 lst::static_length_array_type::static_length_array_type(unsigned int in_alignment,
182 type::cuptr in_element_type,
183 uint64_t in_length) :
184 array_type(in_alignment, std::move(in_element_type)),
185 length{in_length}
186 {
187 }
188
189 bool lst::static_length_array_type::_is_equal(const type& base_other) const noexcept
190 {
191 const auto& other = static_cast<decltype(*this)&>(base_other);
192
193 return array_type::_is_equal(base_other) && this->length == other.length;
194 }
195
196 void lst::static_length_array_type::accept(type_visitor& visitor) const
197 {
198 visitor.visit(*this);
199 }
200
201 lst::dynamic_length_array_type::dynamic_length_array_type(unsigned int in_alignment,
202 type::cuptr in_element_type,
203 std::string in_length_field_name) :
204 array_type(in_alignment, std::move(in_element_type)),
205 length_field_name{std::move(in_length_field_name)}
206 {
207 }
208
209 bool lst::dynamic_length_array_type::_is_equal(const type& base_other) const noexcept
210 {
211 const auto& other = static_cast<decltype(*this)&>(base_other);
212
213 return array_type::_is_equal(base_other) &&
214 this->length_field_name == other.length_field_name;
215 }
216
217 void lst::dynamic_length_array_type::accept(type_visitor& visitor) const
218 {
219 visitor.visit(*this);
220 }
221
222 lst::string_type::string_type(unsigned int in_alignment, enum encoding in_encoding) :
223 type(in_alignment), encoding{in_encoding}
224 {
225 }
226
227 bool lst::string_type::_is_equal(const type& base_other) const noexcept
228 {
229 const auto& other = static_cast<decltype(*this)&>(base_other);
230
231 return this->encoding == other.encoding;
232 }
233
234 lst::static_length_string_type::static_length_string_type(
235 unsigned int in_alignment, enum encoding in_encoding, uint64_t in_length) :
236 string_type(in_alignment, in_encoding), length{in_length}
237 {
238 }
239
240 bool lst::static_length_string_type::_is_equal(const type& base_other) const noexcept
241 {
242 const auto& other = static_cast<decltype(*this)&>(base_other);
243
244 return string_type::_is_equal(base_other) && this->length == other.length;
245 }
246
247 void lst::static_length_string_type::accept(type_visitor& visitor) const
248 {
249 visitor.visit(*this);
250 }
251
252 lst::dynamic_length_string_type::dynamic_length_string_type(unsigned int in_alignment,
253 enum encoding in_encoding,
254 std::string in_length_field_name) :
255 string_type(in_alignment, in_encoding), length_field_name{std::move(in_length_field_name)}
256 {
257 }
258
259 bool lst::dynamic_length_string_type::_is_equal(const type& base_other) const noexcept
260 {
261 const auto& other = static_cast<decltype(*this)&>(base_other);
262
263 return string_type::_is_equal(base_other) &&
264 this->length_field_name == other.length_field_name;
265 }
266
267 void lst::dynamic_length_string_type::accept(type_visitor& visitor) const
268 {
269 visitor.visit(*this);
270 }
271
272 lst::null_terminated_string_type::null_terminated_string_type(unsigned int in_alignment,
273 enum encoding in_encoding) :
274 string_type(in_alignment, in_encoding)
275 {
276 }
277
278 void lst::null_terminated_string_type::accept(type_visitor& visitor) const
279 {
280 visitor.visit(*this);
281 }
282
283 lst::structure_type::structure_type(unsigned int in_alignment, fields in_fields) :
284 type(in_alignment), _fields{std::move(in_fields)}
285 {
286 }
287
288 bool lst::structure_type::_is_equal(const type& base_other) const noexcept
289 {
290 const auto &other = static_cast<decltype(*this)&>(base_other);
291
292 return fields_are_equal(this->_fields, other._fields);
293 }
294
295 void lst::structure_type::accept(type_visitor& visitor) const
296 {
297 visitor.visit(*this);
298 }
299
300 lst::variant_type::variant_type(unsigned int in_alignment,
301 std::string in_tag_name,
302 choices in_choices) :
303 type(in_alignment),
304 tag_name{std::move(in_tag_name)},
305 _choices{std::move(in_choices)}
306 {
307 }
308
309 bool lst::variant_type::_is_equal(const type& base_other) const noexcept
310 {
311 const auto &other = static_cast<decltype(*this)&>(base_other);
312
313 return this->tag_name == other.tag_name &&
314 fields_are_equal(this->_choices, other._choices);
315 }
316
317 void lst::variant_type::accept(type_visitor& visitor) const
318 {
319 visitor.visit(*this);
320 }
This page took 0.035904 seconds and 5 git commands to generate.