4 * Babeltrace CTF IR - Event class
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #define BT_LOG_TAG "EVENT-CLASS"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/ctf-ir/fields-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-ir/event-class.h>
35 #include <babeltrace/ctf-ir/event-class-internal.h>
36 #include <babeltrace/ctf-ir/stream-class.h>
37 #include <babeltrace/ctf-ir/stream-class-internal.h>
38 #include <babeltrace/ctf-ir/trace-internal.h>
39 #include <babeltrace/ctf-ir/validation-internal.h>
40 #include <babeltrace/ctf-ir/utils.h>
41 #include <babeltrace/ref.h>
42 #include <babeltrace/ctf-ir/attributes-internal.h>
43 #include <babeltrace/compiler-internal.h>
44 #include <babeltrace/endian-internal.h>
45 #include <babeltrace/types.h>
46 #include <babeltrace/values-internal.h>
51 void bt_ctf_event_class_destroy(struct bt_object
*obj
);
53 struct bt_ctf_event_class
*bt_ctf_event_class_create(const char *name
)
55 struct bt_value
*obj
= NULL
;
56 struct bt_ctf_event_class
*event_class
= NULL
;
58 BT_LOGD("Creating event class object: name=\"%s\"",
62 BT_LOGW_STR("Invalid parameter: name is NULL.");
66 event_class
= g_new0(struct bt_ctf_event_class
, 1);
68 BT_LOGE_STR("Failed to allocate one event class.");
72 bt_object_init(event_class
, bt_ctf_event_class_destroy
);
73 event_class
->fields
= bt_ctf_field_type_structure_create();
74 if (!event_class
->fields
) {
75 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
80 event_class
->name
= g_string_new(name
);
81 if (!event_class
->name
) {
82 BT_LOGE_STR("Failed to allocate a GString.");
86 event_class
->emf_uri
= g_string_new(NULL
);
87 if (!event_class
->emf_uri
) {
88 BT_LOGE_STR("Failed to allocate a GString.");
92 event_class
->log_level
= BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
;
94 BT_LOGD("Created event class object: addr=%p, name=\"%s\"",
95 event_class
, bt_ctf_event_class_get_name(event_class
));
104 const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class
*event_class
)
106 const char *name
= NULL
;
109 BT_LOGW_STR("Invalid parameter: event class is NULL.");
113 name
= event_class
->name
->str
;
119 int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class
*event_class
)
124 BT_LOGW_STR("Invalid parameter: event class is NULL.");
129 ret
= event_class
->id
;
135 int bt_ctf_event_class_set_id(struct bt_ctf_event_class
*event_class
,
139 int64_t id
= (int64_t) id_param
;
142 BT_LOGW_STR("Invalid parameter: event class is NULL.");
147 if (event_class
->frozen
) {
148 BT_LOGW("Invalid parameter: event class is frozen: "
149 "addr=%p, name=\"%s\", id=%" PRId64
,
150 event_class
, bt_ctf_event_class_get_name(event_class
),
151 bt_ctf_event_class_get_id(event_class
));
157 BT_LOGW("Invalid parameter: invalid event class's ID: "
158 "addr=%p, name=\"%s\", id=%" PRIu64
,
159 event_class
, bt_ctf_event_class_get_name(event_class
),
165 event_class
->id
= id
;
166 BT_LOGV("Set event class's ID: "
167 "addr=%p, name=\"%s\", id=%" PRId64
,
168 event_class
, bt_ctf_event_class_get_name(event_class
), id
);
174 enum bt_ctf_event_class_log_level
bt_ctf_event_class_get_log_level(
175 struct bt_ctf_event_class
*event_class
)
177 enum bt_ctf_event_class_log_level log_level
;
180 BT_LOGW_STR("Invalid parameter: event class is NULL.");
181 log_level
= BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN
;
185 log_level
= event_class
->log_level
;
191 int bt_ctf_event_class_set_log_level(struct bt_ctf_event_class
*event_class
,
192 enum bt_ctf_event_class_log_level log_level
)
197 BT_LOGW_STR("Invalid parameter: event class is NULL.");
202 if (event_class
->frozen
) {
203 BT_LOGW("Invalid parameter: event class is frozen: "
204 "addr=%p, name=\"%s\", id=%" PRId64
,
205 event_class
, bt_ctf_event_class_get_name(event_class
),
206 bt_ctf_event_class_get_id(event_class
));
212 case BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
:
213 case BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY
:
214 case BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT
:
215 case BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL
:
216 case BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR
:
217 case BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING
:
218 case BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE
:
219 case BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO
:
220 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
:
221 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
:
222 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
:
223 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
:
224 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
:
225 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
:
226 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
:
227 case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG
:
230 BT_LOGW("Invalid parameter: unknown event class log level: "
231 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%d",
232 event_class
, bt_ctf_event_class_get_name(event_class
),
233 bt_ctf_event_class_get_id(event_class
), log_level
);
238 event_class
->log_level
= log_level
;
239 BT_LOGV("Set event class's log level: "
240 "addr=%p, name=\"%s\", id=%" PRId64
", log-level=%s",
241 event_class
, bt_ctf_event_class_get_name(event_class
),
242 bt_ctf_event_class_get_id(event_class
),
243 bt_ctf_event_class_log_level_string(log_level
));
249 const char *bt_ctf_event_class_get_emf_uri(
250 struct bt_ctf_event_class
*event_class
)
252 const char *emf_uri
= NULL
;
255 BT_LOGW_STR("Invalid parameter: event class is NULL.");
259 if (event_class
->emf_uri
->len
> 0) {
260 emf_uri
= event_class
->emf_uri
->str
;
267 int bt_ctf_event_class_set_emf_uri(struct bt_ctf_event_class
*event_class
,
273 BT_LOGW_STR("Invalid parameter: event class is NULL.");
278 if (emf_uri
&& strlen(emf_uri
) == 0) {
279 BT_LOGW_STR("Invalid parameter: EMF URI is empty.");
284 if (event_class
->frozen
) {
285 BT_LOGW("Invalid parameter: event class is frozen: "
286 "addr=%p, name=\"%s\", id=%" PRId64
,
287 event_class
, bt_ctf_event_class_get_name(event_class
),
288 bt_ctf_event_class_get_id(event_class
));
294 g_string_assign(event_class
->emf_uri
, emf_uri
);
295 BT_LOGV("Set event class's EMF URI: "
296 "addr=%p, name=\"%s\", id=%" PRId64
", emf-uri=\"%s\"",
297 event_class
, bt_ctf_event_class_get_name(event_class
),
298 bt_ctf_event_class_get_id(event_class
), emf_uri
);
300 g_string_assign(event_class
->emf_uri
, "");
301 BT_LOGV("Reset event class's EMF URI: "
302 "addr=%p, name=\"%s\", id=%" PRId64
,
303 event_class
, bt_ctf_event_class_get_name(event_class
),
304 bt_ctf_event_class_get_id(event_class
));
311 struct bt_ctf_stream_class
*bt_ctf_event_class_get_stream_class(
312 struct bt_ctf_event_class
*event_class
)
315 bt_get(bt_ctf_event_class_borrow_stream_class(event_class
)) :
319 struct bt_ctf_field_type
*bt_ctf_event_class_get_payload_type(
320 struct bt_ctf_event_class
*event_class
)
322 struct bt_ctf_field_type
*payload
= NULL
;
325 BT_LOGW_STR("Invalid parameter: event class is NULL.");
329 bt_get(event_class
->fields
);
330 payload
= event_class
->fields
;
335 int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class
*event_class
,
336 struct bt_ctf_field_type
*payload
)
341 BT_LOGW_STR("Invalid parameter: event class is NULL.");
346 if (payload
&& bt_ctf_field_type_get_type_id(payload
) !=
347 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
348 BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
349 "addr=%p, name=\"%s\", id=%" PRId64
", "
350 "payload-ft-addr=%p, payload-ft-id=%s",
351 event_class
, bt_ctf_event_class_get_name(event_class
),
352 bt_ctf_event_class_get_id(event_class
), payload
,
353 bt_ctf_field_type_id_string(
354 bt_ctf_field_type_get_type_id(payload
)));
359 bt_put(event_class
->fields
);
360 event_class
->fields
= bt_get(payload
);
361 BT_LOGV("Set event class's payload field type: "
362 "event-class-addr=%p, event-class-name=\"%s\", "
363 "event-class-id=%" PRId64
", payload-ft-addr=%p",
364 event_class
, bt_ctf_event_class_get_name(event_class
),
365 bt_ctf_event_class_get_id(event_class
), payload
);
370 int bt_ctf_event_class_add_field(struct bt_ctf_event_class
*event_class
,
371 struct bt_ctf_field_type
*type
,
376 if (!event_class
|| !type
) {
377 BT_LOGW("Invalid parameter: event class or field type is NULL: "
378 "event-class-addr=%p, field-type-addr=%p",
384 if (bt_ctf_validate_identifier(name
)) {
385 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
386 "addr=%p, name=\"%s\", id=%" PRId64
", field-name=\"%s\"",
387 event_class
, bt_ctf_event_class_get_name(event_class
),
388 bt_ctf_event_class_get_id(event_class
),
394 if (event_class
->frozen
) {
395 BT_LOGW("Invalid parameter: event class is frozen: "
396 "addr=%p, name=\"%s\", id=%" PRId64
,
397 event_class
, bt_ctf_event_class_get_name(event_class
),
398 bt_ctf_event_class_get_id(event_class
));
403 if (!event_class
->fields
) {
404 BT_LOGW("Event class has no payload field type: "
405 "addr=%p, name=\"%s\", id=%" PRId64
,
406 event_class
, bt_ctf_event_class_get_name(event_class
),
407 bt_ctf_event_class_get_id(event_class
));
412 assert(bt_ctf_field_type_get_type_id(event_class
->fields
) ==
413 BT_CTF_FIELD_TYPE_ID_STRUCT
);
414 ret
= bt_ctf_field_type_structure_add_field(event_class
->fields
,
416 BT_LOGV("Added field to event class's payload field type: "
417 "event-class-addr=%p, event-class-name=\"%s\", "
418 "event-class-id=%" PRId64
", field-name=\"%s\", ft-addr=%p",
419 event_class
, bt_ctf_event_class_get_name(event_class
),
420 bt_ctf_event_class_get_id(event_class
), name
, type
);
425 int64_t bt_ctf_event_class_get_payload_type_field_count(
426 struct bt_ctf_event_class
*event_class
)
431 BT_LOGW_STR("Invalid parameter: event class is NULL.");
436 if (!event_class
->fields
) {
437 BT_LOGV("Event class has no payload field type: "
438 "addr=%p, name=\"%s\", id=%" PRId64
,
439 event_class
, bt_ctf_event_class_get_name(event_class
),
440 bt_ctf_event_class_get_id(event_class
));
445 assert(bt_ctf_field_type_get_type_id(event_class
->fields
) ==
446 BT_CTF_FIELD_TYPE_ID_STRUCT
);
447 ret
= bt_ctf_field_type_structure_get_field_count(event_class
->fields
);
452 int bt_ctf_event_class_get_payload_type_field_by_index(
453 struct bt_ctf_event_class
*event_class
,
454 const char **field_name
, struct bt_ctf_field_type
**field_type
,
460 BT_LOGW_STR("Invalid parameter: event class is NULL.");
465 if (!event_class
->fields
) {
466 BT_LOGV("Event class has no payload field type: "
467 "addr=%p, name=\"%s\", id=%" PRId64
", index=%" PRIu64
,
468 event_class
, bt_ctf_event_class_get_name(event_class
),
469 bt_ctf_event_class_get_id(event_class
), index
);
474 assert(bt_ctf_field_type_get_type_id(event_class
->fields
) ==
475 BT_CTF_FIELD_TYPE_ID_STRUCT
);
476 ret
= bt_ctf_field_type_structure_get_field(event_class
->fields
,
477 field_name
, field_type
, index
);
482 struct bt_ctf_field_type
*
483 bt_ctf_event_class_get_payload_type_field_type_by_name(
484 struct bt_ctf_event_class
*event_class
, const char *name
)
487 struct bt_ctf_field_type
*field_type
= NULL
;
489 if (!event_class
|| !name
) {
490 BT_LOGW("Invalid parameter: event class or name is NULL: "
491 "event-class-addr=%p, name-addr=%p",
496 if (!event_class
->fields
) {
497 BT_LOGV("Event class has no payload field type: "
498 "addr=%p, name=\"%s\", id=%" PRId64
,
499 event_class
, bt_ctf_event_class_get_name(event_class
),
500 bt_ctf_event_class_get_id(event_class
));
504 assert(bt_ctf_field_type_get_type_id(event_class
->fields
) ==
505 BT_CTF_FIELD_TYPE_ID_STRUCT
);
506 name_quark
= g_quark_try_string(name
);
508 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
513 * No need to increment field_type's reference count since getting it
514 * from the structure already does.
516 field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
517 event_class
->fields
, name
);
522 struct bt_ctf_field_type
*bt_ctf_event_class_get_context_type(
523 struct bt_ctf_event_class
*event_class
)
525 struct bt_ctf_field_type
*context_type
= NULL
;
528 BT_LOGW_STR("Invalid parameter: event class is NULL.");
532 if (!event_class
->context
) {
533 BT_LOGV("Event class has no context field type: "
534 "addr=%p, name=\"%s\", id=%" PRId64
,
535 event_class
, bt_ctf_event_class_get_name(event_class
),
536 bt_ctf_event_class_get_id(event_class
));
540 bt_get(event_class
->context
);
541 context_type
= event_class
->context
;
546 int bt_ctf_event_class_set_context_type(
547 struct bt_ctf_event_class
*event_class
,
548 struct bt_ctf_field_type
*context
)
553 BT_LOGW_STR("Invalid parameter: event class is NULL.");
558 if (event_class
->frozen
) {
559 BT_LOGW("Invalid parameter: event class is frozen: "
560 "addr=%p, name=\"%s\", id=%" PRId64
,
561 event_class
, bt_ctf_event_class_get_name(event_class
),
562 bt_ctf_event_class_get_id(event_class
));
567 if (context
&& bt_ctf_field_type_get_type_id(context
) !=
568 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
569 BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
570 "addr=%p, name=\"%s\", id=%" PRId64
", "
572 event_class
, bt_ctf_event_class_get_name(event_class
),
573 bt_ctf_event_class_get_id(event_class
),
574 bt_ctf_field_type_id_string(
575 bt_ctf_field_type_get_type_id(context
)));
580 bt_put(event_class
->context
);
581 event_class
->context
= bt_get(context
);
582 BT_LOGV("Set event class's context field type: "
583 "event-class-addr=%p, event-class-name=\"%s\", "
584 "event-class-id=%" PRId64
", context-ft-addr=%p",
585 event_class
, bt_ctf_event_class_get_name(event_class
),
586 bt_ctf_event_class_get_id(event_class
), context
);
592 /* Pre-2.0 CTF writer backward compatibility */
593 void bt_ctf_event_class_get(struct bt_ctf_event_class
*event_class
)
598 /* Pre-2.0 CTF writer backward compatibility */
599 void bt_ctf_event_class_put(struct bt_ctf_event_class
*event_class
)
605 void bt_ctf_event_class_destroy(struct bt_object
*obj
)
607 struct bt_ctf_event_class
*event_class
;
609 event_class
= container_of(obj
, struct bt_ctf_event_class
, base
);
610 BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64
,
611 event_class
, bt_ctf_event_class_get_name(event_class
),
612 bt_ctf_event_class_get_id(event_class
));
613 g_string_free(event_class
->name
, TRUE
);
614 g_string_free(event_class
->emf_uri
, TRUE
);
615 BT_LOGD_STR("Putting context field type.");
616 bt_put(event_class
->context
);
617 BT_LOGD_STR("Putting payload field type.");
618 bt_put(event_class
->fields
);
623 void bt_ctf_event_class_freeze(struct bt_ctf_event_class
*event_class
)
627 if (event_class
->frozen
) {
631 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64
,
632 event_class
, bt_ctf_event_class_get_name(event_class
),
633 bt_ctf_event_class_get_id(event_class
));
634 event_class
->frozen
= 1;
635 BT_LOGD_STR("Freezing event class's context field type.");
636 bt_ctf_field_type_freeze(event_class
->context
);
637 BT_LOGD_STR("Freezing event class's payload field type.");
638 bt_ctf_field_type_freeze(event_class
->fields
);
642 int bt_ctf_event_class_serialize(struct bt_ctf_event_class
*event_class
,
643 struct metadata_context
*context
)
646 struct bt_value
*attr_value
= NULL
;
650 BT_LOGD("Serializing event class's metadata: "
651 "event-class-addr=%p, event-class-name=\"%s\", "
652 "event-class-id=%" PRId64
", metadata-context-addr=%p",
653 event_class
, bt_ctf_event_class_get_name(event_class
),
654 bt_ctf_event_class_get_id(event_class
), context
);
655 context
->current_indentation_level
= 1;
656 g_string_assign(context
->field_name
, "");
657 g_string_append(context
->string
, "event {\n");
659 /* Serialize attributes */
660 g_string_append_printf(context
->string
, "\tname = \"%s\";\n",
661 event_class
->name
->str
);
662 assert(event_class
->id
>= 0);
663 g_string_append_printf(context
->string
, "\tid = %" PRId64
";\n",
665 g_string_append_printf(context
->string
, "\tstream_id = %" PRId64
";\n",
666 bt_ctf_stream_class_get_id(
667 bt_ctf_event_class_borrow_stream_class(event_class
)));
669 if (event_class
->log_level
!= BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
) {
670 g_string_append_printf(context
->string
, "\tloglevel = %d;\n",
671 (int) event_class
->log_level
);
674 if (event_class
->emf_uri
->len
> 0) {
675 g_string_append_printf(context
->string
, "\tmodel.emf.uri = \"%s\";\n",
676 event_class
->emf_uri
->str
);
679 /* Serialize context field type */
680 if (event_class
->context
) {
681 g_string_append(context
->string
, "\tcontext := ");
682 BT_LOGD_STR("Serializing event class's context field type metadata.");
683 ret
= bt_ctf_field_type_serialize(event_class
->context
,
686 BT_LOGW("Cannot serialize event class's context field type's metadata: "
690 g_string_append(context
->string
, ";\n");
693 /* Serialize payload field type */
694 if (event_class
->fields
) {
695 g_string_append(context
->string
, "\tfields := ");
696 BT_LOGD_STR("Serializing event class's payload field type metadata.");
697 ret
= bt_ctf_field_type_serialize(event_class
->fields
, context
);
699 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
703 g_string_append(context
->string
, ";\n");
706 g_string_append(context
->string
, "};\n\n");
708 context
->current_indentation_level
= 0;