2 * Copyright (C) 2022 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
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>
18 /* Initialize deserializer map */
19 trace_format_descriptor::deserializer_map
trace_format_descriptor::_deserializer_map
;
21 template <class type
, lttng_trace_format_descriptor_type enumType
>
22 class deserializer_register
{
24 class initializer
: public type
{
28 type::_deserializer_map
[enumType
] = type::deserialize
;
33 deserializer_register()
35 deserializer_register::initializer i
;
39 /* Default destructor for the base type */
40 trace_format_descriptor::~trace_format_descriptor() = default;
42 static deserializer_register
<trace_format_descriptor_ctf1
, LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1
>
44 static deserializer_register
<trace_format_descriptor_ctf2
, LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2
>
47 enum lttng_error_code
trace_format_descriptor::mi_serialize(struct mi_writer
*writer
) const
50 enum lttng_error_code ret_code
;
54 /* Open trace format element. */
55 ret
= mi_lttng_writer_open_element(writer
, config_element_session_trace_format
);
60 /* Serialize underlying descriptor. */
61 ret_code
= this->subtype_mi_serialize(writer
);
62 if (ret_code
!= LTTNG_OK
) {
66 /* Close trace format element. */
67 ret
= mi_lttng_writer_close_element(writer
);
74 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
79 lttng_error_code
trace_format_descriptor_ctf1::subtype_mi_serialize(mi_writer
*writer
) const
82 enum lttng_error_code ret_code
;
86 /* Open ctf1 element. */
87 ret
= mi_lttng_writer_open_element(writer
, config_element_session_trace_format_ctf1
);
92 ret
= mi_lttng_writer_write_element_unsigned_int(
93 writer
, mi_lttng_element_version_major
, _major
);
98 ret
= mi_lttng_writer_write_element_unsigned_int(
99 writer
, mi_lttng_element_version_minor
, _minor
);
104 /* Close ctf1 element. */
105 ret
= mi_lttng_writer_close_element(writer
);
112 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
117 lttng_error_code
trace_format_descriptor_ctf2::subtype_mi_serialize(mi_writer
*writer
) const
120 enum lttng_error_code ret_code
;
122 LTTNG_ASSERT(writer
);
124 /* Open ctf2 element. */
125 ret
= mi_lttng_writer_open_element(writer
, config_element_session_trace_format_ctf2
);
130 ret
= mi_lttng_writer_write_element_unsigned_int(
131 writer
, mi_lttng_element_version_major
, _major
);
136 ret
= mi_lttng_writer_write_element_unsigned_int(
137 writer
, mi_lttng_element_version_minor
, _minor
);
142 /* Close ctf2 element. */
143 ret
= mi_lttng_writer_close_element(writer
);
150 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
155 enum lttng_error_code
trace_format_descriptor::config_serialize(config_writer
*writer
) const
158 enum lttng_error_code ret_code
;
160 LTTNG_ASSERT(writer
);
162 /* Open trace format element. */
163 ret
= config_writer_open_element(writer
, config_element_session_trace_format
);
168 /* Serialize underlying descriptor. */
169 ret_code
= this->subtype_config_serialize(writer
);
170 if (ret_code
!= LTTNG_OK
) {
174 /* Close trace format element. */
175 ret
= config_writer_close_element(writer
);
182 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
187 lttng_error_code
trace_format_descriptor_ctf1::subtype_config_serialize(config_writer
*writer
) const
190 enum lttng_error_code ret_code
;
192 LTTNG_ASSERT(writer
);
194 /* Open ctf1 element. */
195 ret
= config_writer_open_element(writer
, config_element_session_trace_format_ctf1
);
200 /* Close ctf1 element. */
201 ret
= config_writer_close_element(writer
);
208 ret_code
= LTTNG_ERR_SAVE_IO_FAIL
;
213 lttng_error_code
trace_format_descriptor_ctf2::subtype_config_serialize(config_writer
*writer
) const
216 enum lttng_error_code ret_code
;
218 LTTNG_ASSERT(writer
);
220 /* Open ctf2 element. */
221 ret
= config_writer_open_element(writer
, config_element_session_trace_format_ctf2
);
226 /* Close ctf2 element. */
227 ret
= config_writer_close_element(writer
);
234 ret_code
= LTTNG_ERR_SAVE_IO_FAIL
;
239 int trace_format_descriptor::serialize(lttng_payload
*payload
) const
241 struct lttng_trace_format_descriptor_comm comm
= {};
243 LTTNG_ASSERT(payload
);
245 comm
.type
= (int8_t) this->type();
247 return lttng_dynamic_buffer_append(&payload
->buffer
, &comm
, sizeof(comm
));
250 ssize_t
trace_format_descriptor_ctf1::deserialize(lttng_payload_view
*view
, uptr
& descriptor
)
254 /* Nothing to deserialize */
257 trace_format_descriptor::uptr
local_descriptor(new trace_format_descriptor_ctf1
);
258 descriptor
= std::move(local_descriptor
);
262 bool trace_format_descriptor_ctf1::equal_to(const trace_format_descriptor
& rhs
) const
264 trace_format_descriptor_ctf1
const *p
=
265 static_cast<trace_format_descriptor_ctf1
const *>(&rhs
);
267 return _major
== p
->_major
&& _minor
== p
->_minor
;
270 ssize_t
trace_format_descriptor_ctf2::deserialize(lttng_payload_view
*view
, uptr
& descriptor
)
274 /* Nothing to deserialize */
277 trace_format_descriptor::uptr
local_descriptor(new trace_format_descriptor_ctf2
);
278 descriptor
= std::move(local_descriptor
);
282 bool trace_format_descriptor_ctf2::equal_to(const trace_format_descriptor
& rhs
) const
284 trace_format_descriptor_ctf2
const *p
=
285 static_cast<trace_format_descriptor_ctf2
const *>(&rhs
);
287 return _major
== p
->_major
&& _minor
== p
->_minor
;
290 ssize_t
trace_format_descriptor::create_from_payload(lttng_payload_view
*view
, uptr
& descriptor
)
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
));
301 if (!lttng_payload_view_is_valid(&comm_view
)) {
302 /* Payload not large enough to contain the header. */
306 comm
= (typeof(comm
)) comm_view
.buffer
.data
;
307 consumed
+= sizeof(*comm
);
309 lttng_trace_format_descriptor_type type
= (lttng_trace_format_descriptor_type
) comm
->type
;
310 ret
= _deserializer_map
[type
](view
, descriptor
);
322 struct lttng_trace_format_descriptor
*lttng_trace_format_ctf_1_descriptor_create()
324 lttng::trace_format_descriptor
*descriptor
= new lttng::trace_format_descriptor_ctf1();
325 return reinterpret_cast<struct lttng_trace_format_descriptor
*>(descriptor
);
328 struct lttng_trace_format_descriptor
*lttng_trace_format_ctf_2_descriptor_create()
330 lttng::trace_format_descriptor
*descriptor
= new lttng::trace_format_descriptor_ctf2();
331 return reinterpret_cast<struct lttng_trace_format_descriptor
*>(descriptor
);
334 void lttng_trace_format_descriptor_destroy(lttng_trace_format_descriptor
*descriptor
)
336 if (descriptor
== nullptr) {
340 lttng::trace_format_descriptor
*_descriptor
=
341 reinterpret_cast<lttng::trace_format_descriptor
*>(descriptor
);
346 enum lttng_trace_format_descriptor_status
lttng_trace_format_ctf_1_get_version(
347 const struct lttng_trace_format_descriptor
*descriptor
,
351 lttng_trace_format_descriptor_status status
;
352 const lttng::trace_format_descriptor
*tf
;
353 const lttng::trace_format_descriptor_ctf1
*ctf1
;
355 if (descriptor
== nullptr || major
== nullptr || minor
== nullptr) {
356 status
= LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID
;
360 tf
= reinterpret_cast<const lttng::trace_format_descriptor
*>(descriptor
);
362 if (tf
->type() != LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1
) {
363 status
= LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID
;
367 ctf1
= static_cast<const lttng::trace_format_descriptor_ctf1
*>(tf
);
369 *major
= ctf1
->getMajor();
370 *minor
= ctf1
->getMinor();
371 status
= LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK
;
377 enum lttng_trace_format_descriptor_status
lttng_trace_format_ctf_2_get_version(
378 const struct lttng_trace_format_descriptor
*descriptor
,
382 lttng_trace_format_descriptor_status status
;
383 const lttng::trace_format_descriptor
*tf
;
384 const lttng::trace_format_descriptor_ctf2
*ctf2
;
386 if (descriptor
== nullptr || major
== nullptr || minor
== nullptr) {
387 status
= LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID
;
391 tf
= reinterpret_cast<const lttng::trace_format_descriptor
*>(descriptor
);
393 if (tf
->type() != LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2
) {
394 status
= LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID
;
398 ctf2
= static_cast<const lttng::trace_format_descriptor_ctf2
*>(tf
);
400 *major
= ctf2
->getMajor();
401 *minor
= ctf2
->getMinor();
402 status
= LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK
;
407 enum lttng_trace_format_descriptor_type
lttng_trace_format_get_type(
408 const struct lttng_trace_format_descriptor
*descriptor
)
411 return LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_UNKNOWN
;
414 auto tf
= reinterpret_cast<const lttng::trace_format_descriptor
*>(descriptor
);