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