Base lttng_trace_format_descriptor
[lttng-tools.git] / src / common / trace-format-descriptor.cpp
1 /*
2 * Copyright (C) 2022 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <bits/stdint-intn.h>
9 #include <common/mi-lttng.hpp>
10 #include <common/payload-view.hpp>
11 #include <common/payload.hpp>
12 #include <lttng/lttng-error.h>
13 #include <lttng/trace-format-descriptor-internal.hpp>
14 #include <lttng/trace-format-descriptor.h>
15 #include <memory>
16
17 namespace lttng {
18 /* Initialize deserializer map */
19 trace_format_descriptor::deserializer_map trace_format_descriptor::_deserializer_map;
20
21 template <class type, lttng_trace_format_descriptor_type enumType>
22 class deserializer_register {
23 private:
24 class initializer : public type {
25 public:
26 initializer()
27 {
28 type::_deserializer_map[enumType] = type::deserialize;
29 }
30 };
31
32 public:
33 deserializer_register()
34 {
35 deserializer_register::initializer i;
36 }
37 };
38
39 /* Default destructor for the base type */
40 trace_format_descriptor::~trace_format_descriptor() = default;
41
42 static deserializer_register<trace_format_descriptor_ctf1, LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1>
43 ctf1Deserializer;
44 static deserializer_register<trace_format_descriptor_ctf2, LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2>
45 ctf2Deserializer;
46
47 enum lttng_error_code trace_format_descriptor::mi_serialize(struct mi_writer *writer) const
48 {
49 int ret;
50 enum lttng_error_code ret_code;
51
52 LTTNG_ASSERT(writer);
53
54 /* Open trace format element. */
55 ret = mi_lttng_writer_open_element(writer, config_element_session_trace_format);
56 if (ret) {
57 goto mi_error;
58 }
59
60 /* Serialize underlying descriptor. */
61 ret_code = this->subtype_mi_serialize(writer);
62 if (ret_code != LTTNG_OK) {
63 goto end;
64 }
65
66 /* Close trace format element. */
67 ret = mi_lttng_writer_close_element(writer);
68 if (ret) {
69 goto mi_error;
70 }
71 ret_code = LTTNG_OK;
72 goto end;
73 mi_error:
74 ret_code = LTTNG_ERR_MI_IO_FAIL;
75 end:
76 return ret_code;
77 }
78
79 lttng_error_code trace_format_descriptor_ctf1::subtype_mi_serialize(mi_writer *writer) const
80 {
81 int ret;
82 enum lttng_error_code ret_code;
83
84 LTTNG_ASSERT(writer);
85
86 /* Open ctf1 element. */
87 ret = mi_lttng_writer_open_element(writer, config_element_session_trace_format_ctf1);
88 if (ret) {
89 goto mi_error;
90 }
91
92 ret = mi_lttng_writer_write_element_unsigned_int(
93 writer, mi_lttng_element_version_major, _major);
94 if (ret) {
95 goto mi_error;
96 }
97
98 ret = mi_lttng_writer_write_element_unsigned_int(
99 writer, mi_lttng_element_version_minor, _minor);
100 if (ret) {
101 goto mi_error;
102 }
103
104 /* Close ctf1 element. */
105 ret = mi_lttng_writer_close_element(writer);
106 if (ret) {
107 goto mi_error;
108 }
109 ret_code = LTTNG_OK;
110 goto end;
111 mi_error:
112 ret_code = LTTNG_ERR_MI_IO_FAIL;
113 end:
114 return ret_code;
115 }
116
117 lttng_error_code trace_format_descriptor_ctf2::subtype_mi_serialize(mi_writer *writer) const
118 {
119 int ret;
120 enum lttng_error_code ret_code;
121
122 LTTNG_ASSERT(writer);
123
124 /* Open ctf2 element. */
125 ret = mi_lttng_writer_open_element(writer, config_element_session_trace_format_ctf2);
126 if (ret) {
127 goto mi_error;
128 }
129
130 ret = mi_lttng_writer_write_element_unsigned_int(
131 writer, mi_lttng_element_version_major, _major);
132 if (ret) {
133 goto mi_error;
134 }
135
136 ret = mi_lttng_writer_write_element_unsigned_int(
137 writer, mi_lttng_element_version_minor, _minor);
138 if (ret) {
139 goto mi_error;
140 }
141
142 /* Close ctf2 element. */
143 ret = mi_lttng_writer_close_element(writer);
144 if (ret) {
145 goto mi_error;
146 }
147 ret_code = LTTNG_OK;
148 goto end;
149 mi_error:
150 ret_code = LTTNG_ERR_MI_IO_FAIL;
151 end:
152 return ret_code;
153 }
154
155 enum lttng_error_code trace_format_descriptor::config_serialize(config_writer *writer) const
156 {
157 int ret;
158 enum lttng_error_code ret_code;
159
160 LTTNG_ASSERT(writer);
161
162 /* Open trace format element. */
163 ret = config_writer_open_element(writer, config_element_session_trace_format);
164 if (ret) {
165 goto mi_error;
166 }
167
168 /* Serialize underlying descriptor. */
169 ret_code = this->subtype_config_serialize(writer);
170 if (ret_code != LTTNG_OK) {
171 goto end;
172 }
173
174 /* Close trace format element. */
175 ret = config_writer_close_element(writer);
176 if (ret) {
177 goto mi_error;
178 }
179 ret_code = LTTNG_OK;
180 goto end;
181 mi_error:
182 ret_code = LTTNG_ERR_MI_IO_FAIL;
183 end:
184 return ret_code;
185 }
186
187 lttng_error_code trace_format_descriptor_ctf1::subtype_config_serialize(config_writer *writer) const
188 {
189 int ret;
190 enum lttng_error_code ret_code;
191
192 LTTNG_ASSERT(writer);
193
194 /* Open ctf1 element. */
195 ret = config_writer_open_element(writer, config_element_session_trace_format_ctf1);
196 if (ret) {
197 goto error;
198 }
199
200 /* Close ctf1 element. */
201 ret = config_writer_close_element(writer);
202 if (ret) {
203 goto error;
204 }
205 ret_code = LTTNG_OK;
206 goto end;
207 error:
208 ret_code = LTTNG_ERR_SAVE_IO_FAIL;
209 end:
210 return ret_code;
211 }
212
213 lttng_error_code trace_format_descriptor_ctf2::subtype_config_serialize(config_writer *writer) const
214 {
215 int ret;
216 enum lttng_error_code ret_code;
217
218 LTTNG_ASSERT(writer);
219
220 /* Open ctf2 element. */
221 ret = config_writer_open_element(writer, config_element_session_trace_format_ctf2);
222 if (ret) {
223 goto error;
224 }
225
226 /* Close ctf2 element. */
227 ret = config_writer_close_element(writer);
228 if (ret) {
229 goto error;
230 }
231 ret_code = LTTNG_OK;
232 goto end;
233 error:
234 ret_code = LTTNG_ERR_SAVE_IO_FAIL;
235 end:
236 return ret_code;
237 }
238
239 int trace_format_descriptor::serialize(lttng_payload *payload) const
240 {
241 struct lttng_trace_format_descriptor_comm comm = {};
242
243 LTTNG_ASSERT(payload);
244
245 comm.type = (int8_t) this->type();
246
247 return lttng_dynamic_buffer_append(&payload->buffer, &comm, sizeof(comm));
248 }
249
250 ssize_t trace_format_descriptor_ctf1::deserialize(lttng_payload_view *view, uptr& descriptor)
251 {
252 int ret = 0;
253
254 /* Nothing to deserialize */
255 (void) view;
256
257 trace_format_descriptor::uptr local_descriptor(new trace_format_descriptor_ctf1);
258 descriptor = std::move(local_descriptor);
259
260 return ret;
261 }
262 bool trace_format_descriptor_ctf1::equal_to(const trace_format_descriptor& rhs) const
263 {
264 trace_format_descriptor_ctf1 const *p =
265 static_cast<trace_format_descriptor_ctf1 const *>(&rhs);
266
267 return _major == p->_major && _minor == p->_minor;
268 }
269
270 ssize_t trace_format_descriptor_ctf2::deserialize(lttng_payload_view *view, uptr& descriptor)
271 {
272 int ret = 0;
273
274 /* Nothing to deserialize */
275 (void) view;
276
277 trace_format_descriptor::uptr local_descriptor(new trace_format_descriptor_ctf2);
278 descriptor = std::move(local_descriptor);
279
280 return ret;
281 }
282 bool trace_format_descriptor_ctf2::equal_to(const trace_format_descriptor& rhs) const
283 {
284 trace_format_descriptor_ctf2 const *p =
285 static_cast<trace_format_descriptor_ctf2 const *>(&rhs);
286
287 return _major == p->_major && _minor == p->_minor;
288 }
289
290 ssize_t trace_format_descriptor::create_from_payload(lttng_payload_view *view, uptr& descriptor)
291 {
292 ssize_t ret = 0, consumed = 0;
293 const struct lttng_trace_format_descriptor_comm *comm;
294 const struct lttng_payload_view comm_view =
295 lttng_payload_view_from_view(view, 0, sizeof(*comm));
296
297 if (!view) {
298 return -1;
299 }
300
301 if (!lttng_payload_view_is_valid(&comm_view)) {
302 /* Payload not large enough to contain the header. */
303 return -1;
304 }
305
306 comm = (typeof(comm)) comm_view.buffer.data;
307 consumed += sizeof(*comm);
308
309 lttng_trace_format_descriptor_type type = (lttng_trace_format_descriptor_type) comm->type;
310 ret = _deserializer_map[type](view, descriptor);
311 if (ret < 0) {
312 return ret;
313 }
314 consumed += ret;
315
316 ret = consumed;
317
318 return ret;
319 }
320 } // namespace lttng
321
322 struct lttng_trace_format_descriptor *lttng_trace_format_ctf_1_descriptor_create()
323 {
324 lttng::trace_format_descriptor *descriptor = new lttng::trace_format_descriptor_ctf1();
325 return reinterpret_cast<struct lttng_trace_format_descriptor *>(descriptor);
326 }
327
328 struct lttng_trace_format_descriptor *lttng_trace_format_ctf_2_descriptor_create()
329 {
330 lttng::trace_format_descriptor *descriptor = new lttng::trace_format_descriptor_ctf2();
331 return reinterpret_cast<struct lttng_trace_format_descriptor *>(descriptor);
332 }
333
334 void lttng_trace_format_descriptor_destroy(lttng_trace_format_descriptor *descriptor)
335 {
336 if (descriptor == nullptr) {
337 return;
338 }
339
340 lttng::trace_format_descriptor *_descriptor =
341 reinterpret_cast<lttng::trace_format_descriptor *>(descriptor);
342
343 delete _descriptor;
344 }
345
346 enum lttng_trace_format_descriptor_status lttng_trace_format_ctf_1_get_version(
347 const struct lttng_trace_format_descriptor *descriptor,
348 uint64_t *major,
349 uint64_t *minor)
350 {
351 lttng_trace_format_descriptor_status status;
352 const lttng::trace_format_descriptor *tf;
353 const lttng::trace_format_descriptor_ctf1 *ctf1;
354
355 if (descriptor == nullptr || major == nullptr || minor == nullptr) {
356 status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
357 goto end;
358 }
359
360 tf = reinterpret_cast<const lttng::trace_format_descriptor *>(descriptor);
361
362 if (tf->type() != LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1) {
363 status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
364 goto end;
365 }
366
367 ctf1 = static_cast<const lttng::trace_format_descriptor_ctf1 *>(tf);
368
369 *major = ctf1->getMajor();
370 *minor = ctf1->getMinor();
371 status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK;
372
373 end:
374 return status;
375 }
376
377 enum lttng_trace_format_descriptor_status lttng_trace_format_ctf_2_get_version(
378 const struct lttng_trace_format_descriptor *descriptor,
379 uint64_t *major,
380 uint64_t *minor)
381 {
382 lttng_trace_format_descriptor_status status;
383 const lttng::trace_format_descriptor *tf;
384 const lttng::trace_format_descriptor_ctf2 *ctf2;
385
386 if (descriptor == nullptr || major == nullptr || minor == nullptr) {
387 status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
388 goto end;
389 }
390
391 tf = reinterpret_cast<const lttng::trace_format_descriptor *>(descriptor);
392
393 if (tf->type() != LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2) {
394 status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
395 goto end;
396 }
397
398 ctf2 = static_cast<const lttng::trace_format_descriptor_ctf2 *>(tf);
399
400 *major = ctf2->getMajor();
401 *minor = ctf2->getMinor();
402 status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK;
403
404 end:
405 return status;
406 }
407 enum lttng_trace_format_descriptor_type lttng_trace_format_get_type(
408 const struct lttng_trace_format_descriptor *descriptor)
409 {
410 if (!descriptor) {
411 return LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_UNKNOWN;
412 }
413
414 auto tf = reinterpret_cast<const lttng::trace_format_descriptor *>(descriptor);
415
416 return tf->type();
417 }
This page took 0.040949 seconds and 5 git commands to generate.