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