cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / ctf-writer / event-class.c
CommitLineData
3dca2276 1/*
0235b0db
MJ
2 * SPDX-License-Identifier: MIT
3 *
3dca2276
PP
4 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
3dca2276
PP
6 */
7
350ad6c1 8#define BT_LOG_TAG "CTF-WRITER/EVENT-CLASS"
67d2ce02 9#include "logging.h"
3dca2276 10
578e048b
MJ
11#include <glib.h>
12#include <inttypes.h>
13#include <stdlib.h>
14
217cf9d3
PP
15#include <babeltrace2-ctf-writer/event.h>
16#include <babeltrace2-ctf-writer/field-types.h>
17#include <babeltrace2-ctf-writer/object.h>
18#include <babeltrace2-ctf-writer/stream-class.h>
19#include <babeltrace2-ctf-writer/utils.h>
578e048b
MJ
20
21#include "common/assert.h"
22#include "compat/compiler.h"
23#include "compat/endian.h"
24
25#include "assert-pre.h"
26#include "attributes.h"
27#include "event-class.h"
28#include "event.h"
29#include "fields.h"
30#include "field-types.h"
31#include "stream-class.h"
32#include "trace.h"
33#include "utils.h"
34#include "validation.h"
35#include "values.h"
36#include "writer.h"
16ca5ff0 37
e1e02a22 38void bt_ctf_event_class_common_finalize(struct bt_ctf_object *obj)
16ca5ff0
PP
39{
40 struct bt_ctf_event_class_common *event_class;
41
42 event_class = container_of(obj, struct bt_ctf_event_class_common, base);
43 BT_LOGD("Finalizing common event class: addr=%p, name=\"%s\", id=%" PRId64,
44 event_class, bt_ctf_event_class_common_get_name(event_class),
45 bt_ctf_event_class_common_get_id(event_class));
46
47 if (event_class->name) {
48 g_string_free(event_class->name, TRUE);
49 }
50
51 if (event_class->emf_uri) {
52 g_string_free(event_class->emf_uri, TRUE);
53 }
54
55 BT_LOGD_STR("Putting context field type.");
e1e02a22 56 bt_ctf_object_put_ref(event_class->context_field_type);
16ca5ff0 57 BT_LOGD_STR("Putting payload field type.");
e1e02a22 58 bt_ctf_object_put_ref(event_class->payload_field_type);
16ca5ff0
PP
59}
60
16ca5ff0 61int bt_ctf_event_class_common_initialize(struct bt_ctf_event_class_common *event_class,
e1e02a22 62 const char *name, bt_ctf_object_release_func release_func,
16ca5ff0
PP
63 bt_ctf_field_type_structure_create_func ft_struct_create_func)
64{
65 int ret = 0;
66
67 BT_LOGD("Initializing common event class object: name=\"%s\"",
68 name);
e1e02a22 69 bt_ctf_object_init_shared_with_parent(&event_class->base, release_func);
16ca5ff0
PP
70 event_class->payload_field_type = ft_struct_create_func();
71 if (!event_class->payload_field_type) {
72 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
73 goto error;
74 }
75
76 event_class->id = -1;
77 event_class->name = g_string_new(name);
78 if (!event_class->name) {
79 BT_LOGE_STR("Failed to allocate a GString.");
80 goto error;
81 }
82
83 event_class->emf_uri = g_string_new(NULL);
84 if (!event_class->emf_uri) {
85 BT_LOGE_STR("Failed to allocate a GString.");
86 goto error;
87 }
88
89 event_class->log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED;
90 BT_LOGD("Initialized common event class object: addr=%p, name=\"%s\"",
91 event_class, bt_ctf_event_class_common_get_name(event_class));
92 return ret;
93
94error:
95 ret = -1;
96 return ret;
97}
98
16ca5ff0
PP
99void bt_ctf_event_class_common_freeze(struct bt_ctf_event_class_common *event_class)
100{
98b15851 101 BT_ASSERT_DBG(event_class);
16ca5ff0
PP
102
103 if (event_class->frozen) {
104 return;
105 }
106
107 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64,
108 event_class, bt_ctf_event_class_common_get_name(event_class),
109 bt_ctf_event_class_common_get_id(event_class));
110 event_class->frozen = 1;
111 BT_LOGD_STR("Freezing event class's context field type.");
112 bt_ctf_field_type_common_freeze(event_class->context_field_type);
113 BT_LOGD_STR("Freezing event class's payload field type.");
114 bt_ctf_field_type_common_freeze(event_class->payload_field_type);
115}
116
16ca5ff0
PP
117int bt_ctf_event_class_common_validate_single_clock_class(
118 struct bt_ctf_event_class_common *event_class,
119 struct bt_ctf_clock_class **expected_clock_class)
120{
121 int ret = 0;
122
98b15851
PP
123 BT_ASSERT_DBG(event_class);
124 BT_ASSERT_DBG(expected_clock_class);
16ca5ff0
PP
125 ret = bt_ctf_field_type_common_validate_single_clock_class(
126 event_class->context_field_type,
127 expected_clock_class);
128 if (ret) {
129 BT_LOGW("Event class's context field type "
130 "is not recursively mapped to the "
131 "expected clock class: "
132 "event-class-addr=%p, "
133 "event-class-name=\"%s\", "
134 "event-class-id=%" PRId64 ", "
135 "ft-addr=%p",
136 event_class,
137 bt_ctf_event_class_common_get_name(event_class),
138 event_class->id,
139 event_class->context_field_type);
140 goto end;
141 }
142
143 ret = bt_ctf_field_type_common_validate_single_clock_class(
144 event_class->payload_field_type,
145 expected_clock_class);
146 if (ret) {
147 BT_LOGW("Event class's payload field type "
148 "is not recursively mapped to the "
149 "expected clock class: "
150 "event-class-addr=%p, "
151 "event-class-name=\"%s\", "
152 "event-class-id=%" PRId64 ", "
153 "ft-addr=%p",
154 event_class,
155 bt_ctf_event_class_common_get_name(event_class),
156 event_class->id,
157 event_class->payload_field_type);
158 goto end;
159 }
160
161end:
162 return ret;
163}
3dca2276
PP
164
165static
e1e02a22 166void bt_ctf_event_class_destroy(struct bt_ctf_object *obj)
3dca2276 167{
16ca5ff0 168 bt_ctf_event_class_common_finalize(obj);
3dca2276
PP
169 g_free(obj);
170}
171
1353b066 172BT_EXPORT
3dca2276
PP
173struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
174{
175 struct bt_ctf_event_class *ctf_event_class = NULL;
176 int ret;
177
178 if (!name) {
179 BT_LOGW_STR("Invalid parameter: name is NULL.");
180 goto error;
181 }
182
183 BT_LOGD("Creating event class object: name=\"%s\"",
184 name);
185 ctf_event_class = g_new0(struct bt_ctf_event_class, 1);
186 if (!ctf_event_class) {
187 BT_LOGE_STR("Failed to allocate one event class.");
188 goto error;
189 }
190
16ca5ff0 191 ret = bt_ctf_event_class_common_initialize(BT_CTF_TO_COMMON(ctf_event_class),
3dca2276 192 name, bt_ctf_event_class_destroy,
16ca5ff0 193 (bt_ctf_field_type_structure_create_func)
3dca2276
PP
194 bt_ctf_field_type_structure_create);
195 if (ret) {
196 goto error;
197 }
198
199 goto end;
200
201error:
e1e02a22 202 bt_ctf_object_put_ref(ctf_event_class);
3dca2276
PP
203
204end:
205 return ctf_event_class;
206}
207
1353b066 208BT_EXPORT
3dca2276
PP
209const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
210{
16ca5ff0 211 return bt_ctf_event_class_common_get_name(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
212}
213
1353b066 214BT_EXPORT
3dca2276
PP
215int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
216{
16ca5ff0 217 return bt_ctf_event_class_common_get_id(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
218}
219
1353b066 220BT_EXPORT
3dca2276
PP
221int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
222 uint64_t id)
223{
16ca5ff0 224 return bt_ctf_event_class_common_set_id(BT_CTF_TO_COMMON(event_class), id);
3dca2276
PP
225}
226
1353b066 227BT_EXPORT
3dca2276
PP
228enum bt_ctf_event_class_log_level bt_ctf_event_class_get_log_level(
229 struct bt_ctf_event_class *event_class)
230{
16ca5ff0 231 return bt_ctf_event_class_common_get_log_level(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
232}
233
1353b066 234BT_EXPORT
3dca2276
PP
235int bt_ctf_event_class_set_log_level(struct bt_ctf_event_class *event_class,
236 enum bt_ctf_event_class_log_level log_level)
237{
16ca5ff0 238 return bt_ctf_event_class_common_set_log_level(BT_CTF_TO_COMMON(event_class),
3dca2276
PP
239 log_level);
240}
241
1353b066 242BT_EXPORT
3dca2276
PP
243const char *bt_ctf_event_class_get_emf_uri(
244 struct bt_ctf_event_class *event_class)
245{
16ca5ff0 246 return bt_ctf_event_class_common_get_emf_uri(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
247}
248
1353b066 249BT_EXPORT
3dca2276
PP
250int bt_ctf_event_class_set_emf_uri(struct bt_ctf_event_class *event_class,
251 const char *emf_uri)
252{
16ca5ff0 253 return bt_ctf_event_class_common_set_emf_uri(BT_CTF_TO_COMMON(event_class),
3dca2276
PP
254 emf_uri);
255}
256
1353b066 257BT_EXPORT
3dca2276
PP
258struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
259 struct bt_ctf_event_class *event_class)
260{
67d2ce02 261 BT_CTF_ASSERT_PRE_NON_NULL(event_class, "Event class");
e1e02a22 262 return bt_ctf_object_get_ref(bt_ctf_event_class_common_borrow_stream_class(
16ca5ff0 263 BT_CTF_TO_COMMON(event_class)));
3dca2276
PP
264}
265
1353b066 266BT_EXPORT
3dca2276
PP
267struct bt_ctf_field_type *bt_ctf_event_class_get_payload_field_type(
268 struct bt_ctf_event_class *event_class)
269{
e1e02a22 270 return bt_ctf_object_get_ref(bt_ctf_event_class_common_borrow_payload_field_type(
16ca5ff0 271 BT_CTF_TO_COMMON(event_class)));
3dca2276
PP
272}
273
1353b066 274BT_EXPORT
3dca2276
PP
275int bt_ctf_event_class_set_payload_field_type(
276 struct bt_ctf_event_class *event_class,
277 struct bt_ctf_field_type *field_type)
278{
16ca5ff0
PP
279 return bt_ctf_event_class_common_set_payload_field_type(
280 BT_CTF_TO_COMMON(event_class), (void *) field_type);
3dca2276
PP
281}
282
1353b066 283BT_EXPORT
3dca2276
PP
284struct bt_ctf_field_type *bt_ctf_event_class_get_context_field_type(
285 struct bt_ctf_event_class *event_class)
286{
e1e02a22 287 return bt_ctf_object_get_ref(bt_ctf_event_class_common_borrow_context_field_type(
16ca5ff0 288 BT_CTF_TO_COMMON(event_class)));
3dca2276
PP
289}
290
1353b066 291BT_EXPORT
3dca2276
PP
292int bt_ctf_event_class_set_context_field_type(
293 struct bt_ctf_event_class *event_class,
294 struct bt_ctf_field_type *field_type)
295{
16ca5ff0
PP
296 return bt_ctf_event_class_common_set_context_field_type(
297 BT_CTF_TO_COMMON(event_class), (void *) field_type);
3dca2276
PP
298}
299
1353b066 300BT_EXPORT
3dca2276
PP
301int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
302 struct bt_ctf_field_type *type,
303 const char *name)
304{
305 int ret = 0;
306
307 if (!event_class || !type) {
308 BT_LOGW("Invalid parameter: event class or field type is NULL: "
309 "event-class-addr=%p, field-type-addr=%p",
310 event_class, type);
311 ret = -1;
312 goto end;
313 }
314
16ca5ff0 315 if (!bt_ctf_identifier_is_valid(name)) {
3dca2276
PP
316 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
317 "addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"",
318 event_class, bt_ctf_event_class_get_name(event_class),
319 bt_ctf_event_class_get_id(event_class),
320 name);
321 ret = -1;
322 goto end;
323 }
324
325 if (event_class->common.frozen) {
326 BT_LOGW("Invalid parameter: event class is frozen: "
327 "addr=%p, name=\"%s\", id=%" PRId64,
328 event_class, bt_ctf_event_class_get_name(event_class),
329 bt_ctf_event_class_get_id(event_class));
330 ret = -1;
331 goto end;
332 }
333
334 if (!event_class->common.payload_field_type) {
335 BT_LOGW("Event class has no payload field type: "
336 "addr=%p, name=\"%s\", id=%" PRId64,
337 event_class, bt_ctf_event_class_get_name(event_class),
338 bt_ctf_event_class_get_id(event_class));
339 ret = -1;
340 goto end;
341 }
342
98b15851 343 BT_ASSERT_DBG(bt_ctf_field_type_common_get_type_id(
3dca2276 344 event_class->common.payload_field_type) ==
16ca5ff0 345 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
346 ret = bt_ctf_field_type_structure_add_field(
347 (void *) event_class->common.payload_field_type,
348 (void *) type, name);
ef267d12 349 BT_LOGT("Added field to event class's payload field type: "
3dca2276
PP
350 "event-class-addr=%p, event-class-name=\"%s\", "
351 "event-class-id=%" PRId64 ", field-name=\"%s\", ft-addr=%p",
352 event_class, bt_ctf_event_class_get_name(event_class),
353 bt_ctf_event_class_get_id(event_class), name, type);
354end:
355 return ret;
356}
357
1353b066 358BT_EXPORT
3dca2276
PP
359int64_t bt_ctf_event_class_get_payload_type_field_count(
360 struct bt_ctf_event_class *event_class)
361{
362 int64_t ret;
363
364 if (!event_class) {
365 BT_LOGW_STR("Invalid parameter: event class is NULL.");
366 ret = (int64_t) -1;
367 goto end;
368 }
369
370 if (!event_class->common.payload_field_type) {
ef267d12 371 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
372 "addr=%p, name=\"%s\", id=%" PRId64,
373 event_class, bt_ctf_event_class_get_name(event_class),
374 bt_ctf_event_class_get_id(event_class));
375 ret = (int64_t) -1;
376 goto end;
377 }
378
98b15851 379 BT_ASSERT_DBG(bt_ctf_field_type_common_get_type_id(
3dca2276 380 event_class->common.payload_field_type) ==
16ca5ff0
PP
381 BT_CTF_FIELD_TYPE_ID_STRUCT);
382 ret = bt_ctf_field_type_common_structure_get_field_count(
3dca2276
PP
383 event_class->common.payload_field_type);
384end:
385 return ret;
386}
387
1353b066 388BT_EXPORT
3dca2276
PP
389int bt_ctf_event_class_get_payload_type_field_by_index(
390 struct bt_ctf_event_class *event_class,
391 const char **field_name, struct bt_ctf_field_type **field_type,
392 uint64_t index)
393{
394 int ret;
395
396 if (!event_class) {
397 BT_LOGW_STR("Invalid parameter: event class is NULL.");
398 ret = -1;
399 goto end;
400 }
401
402 if (!event_class->common.payload_field_type) {
ef267d12 403 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
404 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
405 event_class, bt_ctf_event_class_get_name(event_class),
406 bt_ctf_event_class_get_id(event_class), index);
407 ret = -1;
408 goto end;
409 }
410
98b15851 411 BT_ASSERT_DBG(bt_ctf_field_type_common_get_type_id(
3dca2276 412 event_class->common.payload_field_type) ==
16ca5ff0 413 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
414 ret = bt_ctf_field_type_structure_get_field_by_index(
415 (void *) event_class->common.payload_field_type,
416 field_name, (void *) field_type, index);
417
418end:
419 return ret;
420}
421
1353b066 422BT_EXPORT
16ca5ff0 423struct bt_ctf_field_type *
3dca2276
PP
424bt_ctf_event_class_get_payload_type_field_type_by_name(
425 struct bt_ctf_event_class *event_class, const char *name)
426{
427 GQuark name_quark;
16ca5ff0 428 struct bt_ctf_field_type *field_type = NULL;
3dca2276
PP
429
430 if (!event_class || !name) {
431 BT_LOGW("Invalid parameter: event class or name is NULL: "
432 "event-class-addr=%p, name-addr=%p",
433 event_class, name);
434 goto end;
435 }
436
437 if (!event_class->common.payload_field_type) {
ef267d12 438 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
439 "addr=%p, name=\"%s\", id=%" PRId64,
440 event_class, bt_ctf_event_class_get_name(event_class),
441 bt_ctf_event_class_get_id(event_class));
442 goto end;
443 }
444
98b15851 445 BT_ASSERT_DBG(bt_ctf_field_type_common_get_type_id(
3dca2276 446 event_class->common.payload_field_type) ==
16ca5ff0 447 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
448 name_quark = g_quark_try_string(name);
449 if (!name_quark) {
450 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
451 goto end;
452 }
453
454 /*
455 * No need to increment field_type's reference count since getting it
456 * from the structure already does.
457 */
458 field_type = (void *)
459 bt_ctf_field_type_structure_get_field_type_by_name(
460 (void *) event_class->common.payload_field_type, name);
461
462end:
463 return field_type;
464}
465
3dca2276
PP
466int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
467 struct metadata_context *context)
468{
469 int ret = 0;
e1e02a22 470 struct bt_ctf_value *attr_value = NULL;
3dca2276 471
98b15851
PP
472 BT_ASSERT_DBG(event_class);
473 BT_ASSERT_DBG(context);
3dca2276
PP
474 BT_LOGD("Serializing event class's metadata: "
475 "event-class-addr=%p, event-class-name=\"%s\", "
476 "event-class-id=%" PRId64 ", metadata-context-addr=%p",
477 event_class, bt_ctf_event_class_get_name(event_class),
478 bt_ctf_event_class_get_id(event_class), context);
479 context->current_indentation_level = 1;
480 g_string_assign(context->field_name, "");
481 g_string_append(context->string, "event {\n");
482
483 /* Serialize attributes */
484 g_string_append_printf(context->string, "\tname = \"%s\";\n",
485 event_class->common.name->str);
98b15851 486 BT_ASSERT_DBG(event_class->common.id >= 0);
3dca2276
PP
487 g_string_append_printf(context->string, "\tid = %" PRId64 ";\n",
488 event_class->common.id);
489 g_string_append_printf(context->string, "\tstream_id = %" PRId64 ";\n",
16ca5ff0
PP
490 bt_ctf_stream_class_common_get_id(
491 bt_ctf_event_class_common_borrow_stream_class(
492 BT_CTF_TO_COMMON(event_class))));
3dca2276
PP
493
494 if (event_class->common.log_level !=
16ca5ff0 495 BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
3dca2276
PP
496 g_string_append_printf(context->string, "\tloglevel = %d;\n",
497 (int) event_class->common.log_level);
498 }
499
500 if (event_class->common.emf_uri->len > 0) {
501 g_string_append_printf(context->string, "\tmodel.emf.uri = \"%s\";\n",
502 event_class->common.emf_uri->str);
503 }
504
505 /* Serialize context field type */
506 if (event_class->common.context_field_type) {
507 g_string_append(context->string, "\tcontext := ");
508 BT_LOGD_STR("Serializing event class's context field type metadata.");
509 ret = bt_ctf_field_type_serialize_recursive(
510 (void *) event_class->common.context_field_type,
511 context);
512 if (ret) {
513 BT_LOGW("Cannot serialize event class's context field type's metadata: "
514 "ret=%d", ret);
515 goto end;
516 }
517 g_string_append(context->string, ";\n");
518 }
519
520 /* Serialize payload field type */
521 if (event_class->common.payload_field_type) {
522 g_string_append(context->string, "\tfields := ");
523 BT_LOGD_STR("Serializing event class's payload field type metadata.");
524 ret = bt_ctf_field_type_serialize_recursive(
525 (void *) event_class->common.payload_field_type,
526 context);
527 if (ret) {
528 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
529 "ret=%d", ret);
530 goto end;
531 }
532 g_string_append(context->string, ";\n");
533 }
534
535 g_string_append(context->string, "};\n\n");
536
537end:
538 context->current_indentation_level = 0;
e1e02a22 539 BT_CTF_OBJECT_PUT_REF_AND_RESET(attr_value);
3dca2276
PP
540 return ret;
541}
542
1353b066 543BT_EXPORT
3dca2276
PP
544struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
545 struct bt_ctf_event_class *event_class, const char *name)
546{
547 GQuark name_quark;
548 struct bt_ctf_field_type *field_type = NULL;
549
550 if (!event_class || !name) {
551 BT_LOGW("Invalid parameter: event class or name is NULL: "
552 "event-class-addr=%p, name-addr=%p",
553 event_class, name);
554 goto end;
555 }
556
557 if (!event_class->common.payload_field_type) {
ef267d12 558 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
559 "addr=%p, name=\"%s\", id=%" PRId64,
560 event_class,
561 bt_ctf_event_class_get_name(event_class),
562 bt_ctf_event_class_get_id(event_class));
563 goto end;
564 }
565
98b15851 566 BT_ASSERT_DBG(event_class->common.payload_field_type->id ==
16ca5ff0 567 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
568 name_quark = g_quark_try_string(name);
569 if (!name_quark) {
570 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
571 goto end;
572 }
573
574 /*
575 * No need to increment field_type's reference count since getting it
576 * from the structure already does.
577 */
e1e02a22 578 field_type = bt_ctf_object_get_ref(
16ca5ff0 579 bt_ctf_field_type_common_structure_borrow_field_type_by_name(
094ff7c0 580 event_class->common.payload_field_type, name));
3dca2276
PP
581
582end:
583 return field_type;
584}
This page took 0.113491 seconds and 4 git commands to generate.