2 * SPDX-License-Identifier: MIT
4 * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
10 #include <babeltrace2/babeltrace.h>
11 #include "common/common.h"
12 #include "common/uuid.h"
13 #include "common/assert.h"
19 enum ctf_field_class_type {
20 CTF_FIELD_CLASS_TYPE_INT,
21 CTF_FIELD_CLASS_TYPE_ENUM,
22 CTF_FIELD_CLASS_TYPE_FLOAT,
23 CTF_FIELD_CLASS_TYPE_STRING,
24 CTF_FIELD_CLASS_TYPE_STRUCT,
25 CTF_FIELD_CLASS_TYPE_ARRAY,
26 CTF_FIELD_CLASS_TYPE_SEQUENCE,
27 CTF_FIELD_CLASS_TYPE_VARIANT,
30 enum ctf_field_class_meaning {
31 CTF_FIELD_CLASS_MEANING_NONE,
32 CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME,
33 CTF_FIELD_CLASS_MEANING_PACKET_END_TIME,
34 CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID,
35 CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID,
36 CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID,
37 CTF_FIELD_CLASS_MEANING_MAGIC,
38 CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT,
39 CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT,
40 CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE,
41 CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE,
42 CTF_FIELD_CLASS_MEANING_UUID,
46 CTF_BYTE_ORDER_UNKNOWN,
47 CTF_BYTE_ORDER_DEFAULT,
48 CTF_BYTE_ORDER_LITTLE,
58 CTF_SCOPE_PACKET_UNKNOWN = -1,
59 CTF_SCOPE_PACKET_HEADER = 0,
60 CTF_SCOPE_PACKET_CONTEXT,
61 CTF_SCOPE_EVENT_HEADER,
62 CTF_SCOPE_EVENT_COMMON_CONTEXT,
63 CTF_SCOPE_EVENT_SPECIFIC_CONTEXT,
64 CTF_SCOPE_EVENT_PAYLOAD,
67 struct ctf_clock_class {
72 int64_t offset_seconds;
73 uint64_t offset_cycles;
78 /* Weak, set during translation */
79 bt_clock_class *ir_cc;
82 struct ctf_field_class {
83 enum ctf_field_class_type type;
84 unsigned int alignment;
88 /* Weak, set during translation. NULL if `in_ir` is false below. */
89 bt_field_class *ir_fc;
92 struct ctf_field_class_bit_array {
93 struct ctf_field_class base;
94 enum ctf_byte_order byte_order;
98 struct ctf_field_class_int {
99 struct ctf_field_class_bit_array base;
100 enum ctf_field_class_meaning meaning;
102 bt_field_class_integer_preferred_display_base disp_base;
103 enum ctf_encoding encoding;
104 int64_t storing_index;
107 struct ctf_clock_class *mapped_clock_class;
122 struct ctf_field_class_enum_mapping {
125 /* Array of `struct ctf_range` */
129 struct ctf_field_class_enum {
130 struct ctf_field_class_int base;
132 /* Array of `struct ctf_field_class_enum_mapping` */
136 struct ctf_field_class_float {
137 struct ctf_field_class_bit_array base;
140 struct ctf_field_class_string {
141 struct ctf_field_class base;
142 enum ctf_encoding encoding;
145 struct ctf_named_field_class {
146 /* Original name which can include a leading `_` */
149 /* Name as translated to trace IR (leading `_` removed) */
153 struct ctf_field_class *fc;
156 struct ctf_field_class_struct {
157 struct ctf_field_class base;
159 /* Array of `struct ctf_named_field_class` */
163 struct ctf_field_path {
166 /* Array of `int64_t` */
170 struct ctf_field_class_variant_range {
171 struct ctf_range range;
172 uint64_t option_index;
175 struct ctf_field_class_variant {
176 struct ctf_field_class base;
178 struct ctf_field_path tag_path;
179 uint64_t stored_tag_index;
181 /* Array of `struct ctf_named_field_class` */
184 /* Array of `struct ctf_field_class_variant_range` */
188 struct ctf_field_class_enum *tag_fc;
191 struct ctf_field_class_array_base {
192 struct ctf_field_class base;
193 struct ctf_field_class *elem_fc;
197 struct ctf_field_class_array {
198 struct ctf_field_class_array_base base;
199 enum ctf_field_class_meaning meaning;
203 struct ctf_field_class_sequence {
204 struct ctf_field_class_array_base base;
206 struct ctf_field_path length_path;
207 uint64_t stored_length_index;
210 struct ctf_field_class_int *length_fc;
213 struct ctf_event_class {
217 bt_event_class_log_level log_level;
219 bool is_log_level_set;
222 struct ctf_field_class *spec_context_fc;
225 struct ctf_field_class *payload_fc;
227 /* Weak, set during translation */
228 bt_event_class *ir_ec;
231 struct ctf_stream_class {
234 bool packets_have_ts_begin;
235 bool packets_have_ts_end;
236 bool has_discarded_events;
237 bool has_discarded_packets;
238 bool discarded_events_have_default_cs;
239 bool discarded_packets_have_default_cs;
242 struct ctf_field_class *packet_context_fc;
245 struct ctf_field_class *event_header_fc;
248 struct ctf_field_class *event_common_context_fc;
250 /* Array of `struct ctf_event_class *`, owned by this */
251 GPtrArray *event_classes;
254 * Hash table mapping event class IDs to `struct ctf_event_class *`,
257 GHashTable *event_classes_by_id;
260 struct ctf_clock_class *default_clock_class;
262 /* Weak, set during translation */
263 bt_stream_class *ir_sc;
266 enum ctf_trace_class_env_entry_type {
267 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
268 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
271 struct ctf_trace_class_env_entry {
272 enum ctf_trace_class_env_entry_type type;
281 struct ctf_trace_class {
286 enum ctf_byte_order default_byte_order;
289 struct ctf_field_class *packet_header_fc;
291 uint64_t stored_value_count;
293 /* Array of `struct ctf_clock_class *` (owned by this) */
294 GPtrArray *clock_classes;
296 /* Array of `struct ctf_stream_class *` */
297 GPtrArray *stream_classes;
299 /* Array of `struct ctf_trace_class_env_entry` */
304 /* Weak, set during translation */
305 bt_trace_class *ir_tc;
309 bool lttng_event_after_packet;
310 bool barectf_event_before_packet;
315 ctf_field_class_bit_array *ctf_field_class_as_bit_array(ctf_field_class *fc)
317 BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_INT ||
318 fc->type == CTF_FIELD_CLASS_TYPE_ENUM ||
319 fc->type == CTF_FIELD_CLASS_TYPE_FLOAT));
320 return (ctf_field_class_bit_array *) fc;
324 ctf_field_class_int *ctf_field_class_as_int(ctf_field_class *fc)
326 BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_INT ||
327 fc->type == CTF_FIELD_CLASS_TYPE_ENUM));
328 return (ctf_field_class_int *) fc;
332 ctf_field_class_enum *ctf_field_class_as_enum(ctf_field_class *fc)
334 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ENUM);
335 return (ctf_field_class_enum *) fc;
339 ctf_field_class_float *ctf_field_class_as_float(ctf_field_class *fc)
341 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_FLOAT);
342 return (ctf_field_class_float *) fc;
346 ctf_field_class_string *ctf_field_class_as_string(ctf_field_class *fc)
348 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRING);
349 return (ctf_field_class_string *) fc;
353 ctf_field_class_struct *ctf_field_class_as_struct(ctf_field_class *fc)
355 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRUCT);
356 return (ctf_field_class_struct *) fc;
360 ctf_field_class_array_base *ctf_field_class_as_array_base(ctf_field_class *fc)
362 BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY ||
363 fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE));
364 return (ctf_field_class_array_base *) fc;
368 ctf_field_class_array *ctf_field_class_as_array(ctf_field_class *fc)
370 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ARRAY);
371 return (ctf_field_class_array *) fc;
375 ctf_field_class_sequence *ctf_field_class_as_sequence(ctf_field_class *fc)
377 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE);
378 return (ctf_field_class_sequence *) fc;
382 ctf_field_class_variant *ctf_field_class_as_variant(
385 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_VARIANT);
386 return (ctf_field_class_variant *) fc;
391 void ctf_field_class_destroy(struct ctf_field_class *fc);
394 void _ctf_field_class_init(struct ctf_field_class *fc,
395 enum ctf_field_class_type type, unsigned int alignment)
399 fc->alignment = alignment;
404 void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array *fc,
405 enum ctf_field_class_type type)
407 _ctf_field_class_init(&fc->base, type, 1);
411 void _ctf_field_class_int_init(struct ctf_field_class_int *fc,
412 enum ctf_field_class_type type)
414 _ctf_field_class_bit_array_init(&fc->base, type);
415 fc->meaning = CTF_FIELD_CLASS_MEANING_NONE;
416 fc->storing_index = -1;
420 void ctf_field_path_init(struct ctf_field_path *field_path)
422 BT_ASSERT(field_path);
423 field_path->path = g_array_new(FALSE, TRUE, sizeof(int64_t));
424 BT_ASSERT(field_path->path);
428 void ctf_field_path_fini(struct ctf_field_path *field_path)
430 BT_ASSERT(field_path);
432 if (field_path->path) {
433 g_array_free(field_path->path, TRUE);
438 void _ctf_named_field_class_init(struct ctf_named_field_class *named_fc)
441 named_fc->name = g_string_new(NULL);
442 BT_ASSERT(named_fc->name);
443 named_fc->orig_name = g_string_new(NULL);
444 BT_ASSERT(named_fc->orig_name);
448 void _ctf_named_field_class_fini(struct ctf_named_field_class *named_fc)
452 if (named_fc->name) {
453 g_string_free(named_fc->name, TRUE);
456 if (named_fc->orig_name) {
457 g_string_free(named_fc->orig_name, TRUE);
460 ctf_field_class_destroy(named_fc->fc);
464 void _ctf_field_class_enum_mapping_init(
465 struct ctf_field_class_enum_mapping *mapping)
468 mapping->label = g_string_new(NULL);
469 BT_ASSERT(mapping->label);
470 mapping->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_range));
471 BT_ASSERT(mapping->ranges);
475 void _ctf_field_class_enum_mapping_fini(
476 struct ctf_field_class_enum_mapping *mapping)
480 if (mapping->label) {
481 g_string_free(mapping->label, TRUE);
484 if (mapping->ranges) {
485 g_array_free(mapping->ranges, TRUE);
490 struct ctf_field_class_int *ctf_field_class_int_create(void)
492 struct ctf_field_class_int *fc = g_new0(struct ctf_field_class_int, 1);
495 _ctf_field_class_int_init(fc, CTF_FIELD_CLASS_TYPE_INT);
500 struct ctf_field_class_float *ctf_field_class_float_create(void)
502 struct ctf_field_class_float *fc =
503 g_new0(struct ctf_field_class_float, 1);
506 _ctf_field_class_bit_array_init(&fc->base, CTF_FIELD_CLASS_TYPE_FLOAT);
511 struct ctf_field_class_string *ctf_field_class_string_create(void)
513 struct ctf_field_class_string *fc =
514 g_new0(struct ctf_field_class_string, 1);
517 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRING, 8);
522 struct ctf_field_class_enum *ctf_field_class_enum_create(void)
524 struct ctf_field_class_enum *fc = g_new0(struct ctf_field_class_enum, 1);
527 _ctf_field_class_int_init(&fc->base, CTF_FIELD_CLASS_TYPE_ENUM);
528 fc->mappings = g_array_new(FALSE, TRUE,
529 sizeof(struct ctf_field_class_enum_mapping));
530 BT_ASSERT(fc->mappings);
535 struct ctf_field_class_struct *ctf_field_class_struct_create(void)
537 struct ctf_field_class_struct *fc =
538 g_new0(struct ctf_field_class_struct, 1);
541 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRUCT, 1);
542 fc->members = g_array_new(FALSE, TRUE,
543 sizeof(struct ctf_named_field_class));
544 BT_ASSERT(fc->members);
545 fc->base.is_compound = true;
550 struct ctf_field_class_variant *ctf_field_class_variant_create(void)
552 struct ctf_field_class_variant *fc =
553 g_new0(struct ctf_field_class_variant, 1);
556 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_VARIANT, 1);
557 fc->options = g_array_new(FALSE, TRUE,
558 sizeof(struct ctf_named_field_class));
559 BT_ASSERT(fc->options);
560 fc->ranges = g_array_new(FALSE, TRUE,
561 sizeof(struct ctf_field_class_variant_range));
562 BT_ASSERT(fc->ranges);
563 fc->tag_ref = g_string_new(NULL);
564 BT_ASSERT(fc->tag_ref);
565 ctf_field_path_init(&fc->tag_path);
566 fc->base.is_compound = true;
571 struct ctf_field_class_array *ctf_field_class_array_create(void)
573 struct ctf_field_class_array *fc =
574 g_new0(struct ctf_field_class_array, 1);
577 _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_ARRAY, 1);
578 fc->base.base.is_compound = true;
583 struct ctf_field_class_sequence *ctf_field_class_sequence_create(void)
585 struct ctf_field_class_sequence *fc =
586 g_new0(struct ctf_field_class_sequence, 1);
589 _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_SEQUENCE, 1);
590 fc->length_ref = g_string_new(NULL);
591 BT_ASSERT(fc->length_ref);
592 ctf_field_path_init(&fc->length_path);
593 fc->base.base.is_compound = true;
598 void _ctf_field_class_int_destroy(struct ctf_field_class_int *fc)
605 void _ctf_field_class_enum_destroy(struct ctf_field_class_enum *fc)
612 for (i = 0; i < fc->mappings->len; i++) {
613 struct ctf_field_class_enum_mapping *mapping =
614 &g_array_index(fc->mappings,
615 struct ctf_field_class_enum_mapping, i);
617 _ctf_field_class_enum_mapping_fini(mapping);
620 g_array_free(fc->mappings, TRUE);
627 void _ctf_field_class_float_destroy(struct ctf_field_class_float *fc)
634 void _ctf_field_class_string_destroy(struct ctf_field_class_string *fc)
641 void _ctf_field_class_struct_destroy(struct ctf_field_class_struct *fc)
648 for (i = 0; i < fc->members->len; i++) {
649 struct ctf_named_field_class *named_fc =
650 &g_array_index(fc->members,
651 struct ctf_named_field_class, i);
653 _ctf_named_field_class_fini(named_fc);
656 g_array_free(fc->members, TRUE);
663 void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base *fc)
666 ctf_field_class_destroy(fc->elem_fc);
670 void _ctf_field_class_array_destroy(struct ctf_field_class_array *fc)
673 _ctf_field_class_array_base_fini(&fc->base);
678 void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence *fc)
681 _ctf_field_class_array_base_fini(&fc->base);
683 if (fc->length_ref) {
684 g_string_free(fc->length_ref, TRUE);
687 ctf_field_path_fini(&fc->length_path);
692 void _ctf_field_class_variant_destroy(struct ctf_field_class_variant *fc)
699 for (i = 0; i < fc->options->len; i++) {
700 struct ctf_named_field_class *named_fc =
701 &g_array_index(fc->options,
702 struct ctf_named_field_class, i);
704 _ctf_named_field_class_fini(named_fc);
707 g_array_free(fc->options, TRUE);
711 g_array_free(fc->ranges, TRUE);
715 g_string_free(fc->tag_ref, TRUE);
718 ctf_field_path_fini(&fc->tag_path);
723 void ctf_field_class_destroy(struct ctf_field_class *fc)
730 case CTF_FIELD_CLASS_TYPE_INT:
731 _ctf_field_class_int_destroy(ctf_field_class_as_int(fc));
733 case CTF_FIELD_CLASS_TYPE_ENUM:
734 _ctf_field_class_enum_destroy(ctf_field_class_as_enum(fc));
736 case CTF_FIELD_CLASS_TYPE_FLOAT:
737 _ctf_field_class_float_destroy(ctf_field_class_as_float(fc));
739 case CTF_FIELD_CLASS_TYPE_STRING:
740 _ctf_field_class_string_destroy(ctf_field_class_as_string(fc));
742 case CTF_FIELD_CLASS_TYPE_STRUCT:
743 _ctf_field_class_struct_destroy(ctf_field_class_as_struct(fc));
745 case CTF_FIELD_CLASS_TYPE_ARRAY:
746 _ctf_field_class_array_destroy(ctf_field_class_as_array(fc));
748 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
749 _ctf_field_class_sequence_destroy(ctf_field_class_as_sequence(fc));
751 case CTF_FIELD_CLASS_TYPE_VARIANT:
752 _ctf_field_class_variant_destroy(ctf_field_class_as_variant(fc));
760 struct ctf_range *ctf_field_class_enum_mapping_borrow_range_by_index(
761 struct ctf_field_class_enum_mapping *mapping, uint64_t index)
763 BT_ASSERT_DBG(mapping);
764 BT_ASSERT_DBG(index < mapping->ranges->len);
765 return &g_array_index(mapping->ranges, struct ctf_range, index);
769 struct ctf_field_class_enum_mapping *ctf_field_class_enum_borrow_mapping_by_index(
770 struct ctf_field_class_enum *fc, uint64_t index)
773 BT_ASSERT_DBG(index < fc->mappings->len);
774 return &g_array_index(fc->mappings, struct ctf_field_class_enum_mapping,
779 struct ctf_field_class_enum_mapping *ctf_field_class_enum_borrow_mapping_by_label(
780 struct ctf_field_class_enum *fc, const char *label)
782 struct ctf_field_class_enum_mapping *ret_mapping = NULL;
786 BT_ASSERT_DBG(label);
788 for (i = 0; i < fc->mappings->len; i++) {
789 struct ctf_field_class_enum_mapping *mapping =
790 ctf_field_class_enum_borrow_mapping_by_index(fc, i);
792 if (strcmp(mapping->label->str, label) == 0) {
793 ret_mapping = mapping;
803 void ctf_field_class_enum_map_range(struct ctf_field_class_enum *fc,
804 const char *label, uint64_t u_lower, uint64_t u_upper)
806 struct ctf_field_class_enum_mapping *mapping = NULL;
807 struct ctf_range range = {
820 for (i = 0; i < fc->mappings->len; i++) {
821 mapping = ctf_field_class_enum_borrow_mapping_by_index(
824 if (strcmp(mapping->label->str, label) == 0) {
829 if (i == fc->mappings->len) {
834 g_array_set_size(fc->mappings, fc->mappings->len + 1);
835 mapping = ctf_field_class_enum_borrow_mapping_by_index(
836 fc, fc->mappings->len - 1);
837 _ctf_field_class_enum_mapping_init(mapping);
838 g_string_assign(mapping->label, label);
841 g_array_append_val(mapping->ranges, range);
845 struct ctf_named_field_class *ctf_field_class_struct_borrow_member_by_index(
846 struct ctf_field_class_struct *fc, uint64_t index)
849 BT_ASSERT_DBG(index < fc->members->len);
850 return &g_array_index(fc->members, struct ctf_named_field_class,
855 struct ctf_named_field_class *ctf_field_class_struct_borrow_member_by_name(
856 struct ctf_field_class_struct *fc, const char *name)
859 struct ctf_named_field_class *ret_named_fc = NULL;
864 for (i = 0; i < fc->members->len; i++) {
865 struct ctf_named_field_class *named_fc =
866 ctf_field_class_struct_borrow_member_by_index(fc, i);
868 if (strcmp(name, named_fc->name->str) == 0) {
869 ret_named_fc = named_fc;
879 struct ctf_field_class *ctf_field_class_struct_borrow_member_field_class_by_name(
880 struct ctf_field_class_struct *struct_fc, const char *name)
882 struct ctf_named_field_class *named_fc = NULL;
883 struct ctf_field_class *fc = NULL;
889 named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name);
901 struct ctf_field_class_int *
902 ctf_field_class_struct_borrow_member_int_field_class_by_name(
903 struct ctf_field_class_struct *struct_fc, const char *name)
905 struct ctf_field_class_int *int_fc = NULL;
907 int_fc = ctf_field_class_as_int(
908 ctf_field_class_struct_borrow_member_field_class_by_name(
914 if (int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_INT &&
915 int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_ENUM) {
925 void _ctf_named_field_class_unescape_orig_name(
926 struct ctf_named_field_class *named_fc)
928 const char *name = named_fc->orig_name->str;
930 if (name[0] == '_') {
934 g_string_assign(named_fc->name, name);
938 void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc,
939 const char *orig_name, struct ctf_field_class *member_fc)
941 struct ctf_named_field_class *named_fc;
944 BT_ASSERT(orig_name);
945 g_array_set_size(fc->members, fc->members->len + 1);
947 named_fc = &g_array_index(fc->members, struct ctf_named_field_class,
948 fc->members->len - 1);
949 _ctf_named_field_class_init(named_fc);
950 g_string_assign(named_fc->orig_name, orig_name);
951 _ctf_named_field_class_unescape_orig_name(named_fc);
952 named_fc->fc = member_fc;
954 if (member_fc->alignment > fc->base.alignment) {
955 fc->base.alignment = member_fc->alignment;
960 struct ctf_named_field_class *ctf_field_class_variant_borrow_option_by_index(
961 struct ctf_field_class_variant *fc, uint64_t index)
964 BT_ASSERT_DBG(index < fc->options->len);
965 return &g_array_index(fc->options, struct ctf_named_field_class,
970 struct ctf_named_field_class *ctf_field_class_variant_borrow_option_by_name(
971 struct ctf_field_class_variant *fc, const char *name)
974 struct ctf_named_field_class *ret_named_fc = NULL;
979 for (i = 0; i < fc->options->len; i++) {
980 struct ctf_named_field_class *named_fc =
981 ctf_field_class_variant_borrow_option_by_index(fc, i);
983 if (strcmp(name, named_fc->name->str) == 0) {
984 ret_named_fc = named_fc;
994 struct ctf_field_class_variant_range *
995 ctf_field_class_variant_borrow_range_by_index(
996 struct ctf_field_class_variant *fc, uint64_t index)
999 BT_ASSERT_DBG(index < fc->ranges->len);
1000 return &g_array_index(fc->ranges, struct ctf_field_class_variant_range,
1005 void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc,
1006 const char *orig_name, struct ctf_field_class *option_fc)
1008 struct ctf_named_field_class *named_fc;
1011 BT_ASSERT(orig_name);
1012 g_array_set_size(fc->options, fc->options->len + 1);
1014 named_fc = &g_array_index(fc->options, struct ctf_named_field_class,
1015 fc->options->len - 1);
1016 _ctf_named_field_class_init(named_fc);
1017 g_string_assign(named_fc->orig_name, orig_name);
1018 _ctf_named_field_class_unescape_orig_name(named_fc);
1019 named_fc->fc = option_fc;
1023 void ctf_field_class_variant_set_tag_field_class(
1024 struct ctf_field_class_variant *fc,
1025 struct ctf_field_class_enum *tag_fc)
1031 fc->tag_fc = tag_fc;
1033 for (option_i = 0; option_i < fc->options->len; option_i++) {
1035 struct ctf_named_field_class *named_fc =
1036 ctf_field_class_variant_borrow_option_by_index(
1038 struct ctf_field_class_enum_mapping *mapping;
1040 mapping = ctf_field_class_enum_borrow_mapping_by_label(
1041 tag_fc, named_fc->orig_name->str);
1046 for (range_i = 0; range_i < mapping->ranges->len;
1048 struct ctf_range *range =
1049 ctf_field_class_enum_mapping_borrow_range_by_index(
1051 struct ctf_field_class_variant_range var_range;
1053 var_range.range = *range;
1054 var_range.option_index = option_i;
1055 g_array_append_val(fc->ranges, var_range);
1061 struct ctf_field_class *ctf_field_class_compound_borrow_field_class_by_index(
1062 struct ctf_field_class *comp_fc, uint64_t index)
1064 struct ctf_field_class *fc = NULL;
1066 switch (comp_fc->type) {
1067 case CTF_FIELD_CLASS_TYPE_STRUCT:
1069 struct ctf_named_field_class *named_fc =
1070 ctf_field_class_struct_borrow_member_by_index(
1071 (struct ctf_field_class_struct *) comp_fc, index);
1073 BT_ASSERT_DBG(named_fc);
1077 case CTF_FIELD_CLASS_TYPE_VARIANT:
1079 struct ctf_named_field_class *named_fc =
1080 ctf_field_class_variant_borrow_option_by_index(
1081 (struct ctf_field_class_variant *) comp_fc, index);
1083 BT_ASSERT_DBG(named_fc);
1087 case CTF_FIELD_CLASS_TYPE_ARRAY:
1088 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1090 struct ctf_field_class_array_base *array_fc =
1091 (struct ctf_field_class_array_base *) comp_fc;
1093 fc = array_fc->elem_fc;
1104 uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class *fc)
1106 uint64_t field_count;
1109 case CTF_FIELD_CLASS_TYPE_STRUCT:
1111 struct ctf_field_class_struct *struct_fc =
1112 (struct ctf_field_class_struct *) fc;
1114 field_count = struct_fc->members->len;
1117 case CTF_FIELD_CLASS_TYPE_VARIANT:
1119 struct ctf_field_class_variant *var_fc =
1120 (struct ctf_field_class_variant *) fc;
1122 field_count = var_fc->options->len;
1125 case CTF_FIELD_CLASS_TYPE_ARRAY:
1126 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1128 * Array and sequence types always contain a single
1129 * member (the element type).
1141 int64_t ctf_field_class_compound_get_field_class_index_from_orig_name(
1142 struct ctf_field_class *fc, const char *orig_name)
1144 int64_t ret_index = -1;
1148 case CTF_FIELD_CLASS_TYPE_STRUCT:
1150 struct ctf_field_class_struct *struct_fc =
1151 (struct ctf_field_class_struct *) fc;
1153 for (i = 0; i < struct_fc->members->len; i++) {
1154 struct ctf_named_field_class *named_fc =
1155 ctf_field_class_struct_borrow_member_by_index(
1158 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1159 ret_index = (int64_t) i;
1166 case CTF_FIELD_CLASS_TYPE_VARIANT:
1168 struct ctf_field_class_variant *var_fc
1169 = (struct ctf_field_class_variant *) fc;
1171 for (i = 0; i < var_fc->options->len; i++) {
1172 struct ctf_named_field_class *named_fc =
1173 ctf_field_class_variant_borrow_option_by_index(
1176 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1177 ret_index = (int64_t) i;
1193 void ctf_field_path_append_index(struct ctf_field_path *fp, int64_t index)
1196 g_array_append_val(fp->path, index);
1200 int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path *fp,
1204 BT_ASSERT_DBG(index < fp->path->len);
1205 return g_array_index(fp->path, int64_t, index);
1209 void ctf_field_path_clear(struct ctf_field_path *fp)
1212 g_array_set_size(fp->path, 0);
1216 const char *ctf_scope_string(enum ctf_scope scope)
1219 case CTF_SCOPE_PACKET_HEADER:
1220 return "PACKET_HEADER";
1221 case CTF_SCOPE_PACKET_CONTEXT:
1222 return "PACKET_CONTEXT";
1223 case CTF_SCOPE_EVENT_HEADER:
1224 return "EVENT_HEADER";
1225 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1226 return "EVENT_COMMON_CONTEXT";
1227 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1228 return "EVENT_SPECIFIC_CONTEXT";
1229 case CTF_SCOPE_EVENT_PAYLOAD:
1230 return "EVENT_PAYLOAD";
1237 GString *ctf_field_path_string(struct ctf_field_path *path)
1239 GString *str = g_string_new(NULL);
1248 g_string_append_printf(str, "[%s", ctf_scope_string(path->root));
1250 for (i = 0; i < path->path->len; i++) {
1251 g_string_append_printf(str, ", %" PRId64,
1252 ctf_field_path_borrow_index_by_index(path, i));
1255 g_string_append(str, "]");
1262 struct ctf_field_class *ctf_field_path_borrow_field_class(
1263 struct ctf_field_path *field_path,
1264 struct ctf_trace_class *tc,
1265 struct ctf_stream_class *sc,
1266 struct ctf_event_class *ec)
1269 struct ctf_field_class *fc;
1271 switch (field_path->root) {
1272 case CTF_SCOPE_PACKET_HEADER:
1273 fc = tc->packet_header_fc;
1275 case CTF_SCOPE_PACKET_CONTEXT:
1276 fc = sc->packet_context_fc;
1278 case CTF_SCOPE_EVENT_HEADER:
1279 fc = sc->event_header_fc;
1281 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1282 fc = sc->event_common_context_fc;
1284 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1285 fc = ec->spec_context_fc;
1287 case CTF_SCOPE_EVENT_PAYLOAD:
1288 fc = ec->payload_fc;
1296 for (i = 0; i < field_path->path->len; i++) {
1297 int64_t child_index =
1298 ctf_field_path_borrow_index_by_index(field_path, i);
1299 struct ctf_field_class *child_fc =
1300 ctf_field_class_compound_borrow_field_class_by_index(
1302 BT_ASSERT_DBG(child_fc);
1311 struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc);
1314 void ctf_field_class_bit_array_copy_content(
1315 struct ctf_field_class_bit_array *dst_fc,
1316 struct ctf_field_class_bit_array *src_fc)
1320 dst_fc->byte_order = src_fc->byte_order;
1321 dst_fc->size = src_fc->size;
1325 void ctf_field_class_int_copy_content(
1326 struct ctf_field_class_int *dst_fc,
1327 struct ctf_field_class_int *src_fc)
1329 ctf_field_class_bit_array_copy_content(&dst_fc->base, &src_fc->base);
1330 dst_fc->meaning = src_fc->meaning;
1331 dst_fc->is_signed = src_fc->is_signed;
1332 dst_fc->disp_base = src_fc->disp_base;
1333 dst_fc->encoding = src_fc->encoding;
1334 dst_fc->mapped_clock_class = src_fc->mapped_clock_class;
1335 dst_fc->storing_index = src_fc->storing_index;
1339 struct ctf_field_class_int *_ctf_field_class_int_copy(
1340 struct ctf_field_class_int *fc)
1342 struct ctf_field_class_int *copy_fc = ctf_field_class_int_create();
1345 ctf_field_class_int_copy_content(copy_fc, fc);
1350 struct ctf_field_class_enum *_ctf_field_class_enum_copy(
1351 struct ctf_field_class_enum *fc)
1353 struct ctf_field_class_enum *copy_fc = ctf_field_class_enum_create();
1357 ctf_field_class_int_copy_content(©_fc->base, &fc->base);
1359 for (i = 0; i < fc->mappings->len; i++) {
1362 struct ctf_field_class_enum_mapping *mapping =
1363 &g_array_index(fc->mappings,
1364 struct ctf_field_class_enum_mapping, i);
1366 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
1367 struct ctf_range *range =
1368 &g_array_index(mapping->ranges,
1369 struct ctf_range, range_i);
1371 ctf_field_class_enum_map_range(copy_fc,
1372 mapping->label->str, range->lower.u,
1381 struct ctf_field_class_float *_ctf_field_class_float_copy(
1382 struct ctf_field_class_float *fc)
1384 struct ctf_field_class_float *copy_fc = ctf_field_class_float_create();
1387 ctf_field_class_bit_array_copy_content(©_fc->base, &fc->base);
1392 struct ctf_field_class_string *_ctf_field_class_string_copy(
1393 struct ctf_field_class_string *fc)
1395 struct ctf_field_class_string *copy_fc = ctf_field_class_string_create();
1402 struct ctf_field_class_struct *_ctf_field_class_struct_copy(
1403 struct ctf_field_class_struct *fc)
1405 struct ctf_field_class_struct *copy_fc = ctf_field_class_struct_create();
1410 for (i = 0; i < fc->members->len; i++) {
1411 struct ctf_named_field_class *named_fc =
1412 &g_array_index(fc->members,
1413 struct ctf_named_field_class, i);
1415 ctf_field_class_struct_append_member(copy_fc,
1416 named_fc->name->str,
1417 ctf_field_class_copy(named_fc->fc));
1424 void ctf_field_path_copy_content(struct ctf_field_path *dst_fp,
1425 struct ctf_field_path *src_fp)
1431 dst_fp->root = src_fp->root;
1432 ctf_field_path_clear(dst_fp);
1434 for (i = 0; i < src_fp->path->len; i++) {
1435 int64_t index = ctf_field_path_borrow_index_by_index(
1438 ctf_field_path_append_index(dst_fp, index);
1443 struct ctf_field_class_variant *_ctf_field_class_variant_copy(
1444 struct ctf_field_class_variant *fc)
1446 struct ctf_field_class_variant *copy_fc =
1447 ctf_field_class_variant_create();
1452 for (i = 0; i < fc->options->len; i++) {
1453 struct ctf_named_field_class *named_fc =
1454 &g_array_index(fc->options,
1455 struct ctf_named_field_class, i);
1457 ctf_field_class_variant_append_option(copy_fc,
1458 named_fc->name->str,
1459 ctf_field_class_copy(named_fc->fc));
1462 for (i = 0; i < fc->ranges->len; i++) {
1463 struct ctf_field_class_variant_range *range =
1464 &g_array_index(fc->ranges,
1465 struct ctf_field_class_variant_range, i);
1467 g_array_append_val(copy_fc->ranges, *range);
1470 ctf_field_path_copy_content(©_fc->tag_path, &fc->tag_path);
1471 g_string_assign(copy_fc->tag_ref, fc->tag_ref->str);
1472 copy_fc->stored_tag_index = fc->stored_tag_index;
1477 void ctf_field_class_array_base_copy_content(
1478 struct ctf_field_class_array_base *dst_fc,
1479 struct ctf_field_class_array_base *src_fc)
1483 dst_fc->elem_fc = ctf_field_class_copy(src_fc->elem_fc);
1484 dst_fc->is_text = src_fc->is_text;
1488 struct ctf_field_class_array *_ctf_field_class_array_copy(
1489 struct ctf_field_class_array *fc)
1491 struct ctf_field_class_array *copy_fc = ctf_field_class_array_create();
1494 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1495 copy_fc->length = fc->length;
1500 struct ctf_field_class_sequence *_ctf_field_class_sequence_copy(
1501 struct ctf_field_class_sequence *fc)
1503 struct ctf_field_class_sequence *copy_fc =
1504 ctf_field_class_sequence_create();
1507 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1508 ctf_field_path_copy_content(©_fc->length_path, &fc->length_path);
1509 g_string_assign(copy_fc->length_ref, fc->length_ref->str);
1510 copy_fc->stored_length_index = fc->stored_length_index;
1515 struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc)
1517 struct ctf_field_class *copy_fc = NULL;
1524 * Translation should not have happened yet.
1526 BT_ASSERT(!fc->ir_fc);
1529 case CTF_FIELD_CLASS_TYPE_INT:
1530 copy_fc = &_ctf_field_class_int_copy(ctf_field_class_as_int (fc))->base.base;
1532 case CTF_FIELD_CLASS_TYPE_ENUM:
1533 copy_fc = &_ctf_field_class_enum_copy(ctf_field_class_as_enum (fc))->base.base.base;
1535 case CTF_FIELD_CLASS_TYPE_FLOAT:
1536 copy_fc = &_ctf_field_class_float_copy(ctf_field_class_as_float (fc))->base.base;
1538 case CTF_FIELD_CLASS_TYPE_STRING:
1539 copy_fc = &_ctf_field_class_string_copy(ctf_field_class_as_string (fc))->base;
1541 case CTF_FIELD_CLASS_TYPE_STRUCT:
1542 copy_fc = &_ctf_field_class_struct_copy(ctf_field_class_as_struct (fc))->base;
1544 case CTF_FIELD_CLASS_TYPE_ARRAY:
1545 copy_fc = &_ctf_field_class_array_copy(ctf_field_class_as_array(fc))->base.base;
1547 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1548 copy_fc = &_ctf_field_class_sequence_copy(ctf_field_class_as_sequence (fc))->base.base;
1550 case CTF_FIELD_CLASS_TYPE_VARIANT:
1551 copy_fc = &_ctf_field_class_variant_copy(ctf_field_class_as_variant (fc))->base;
1557 copy_fc->type = fc->type;
1558 copy_fc->alignment = fc->alignment;
1559 copy_fc->in_ir = fc->in_ir;
1566 struct ctf_event_class *ctf_event_class_create(void)
1568 struct ctf_event_class *ec = g_new0(struct ctf_event_class, 1);
1571 ec->name = g_string_new(NULL);
1572 BT_ASSERT(ec->name);
1573 ec->emf_uri = g_string_new(NULL);
1574 BT_ASSERT(ec->emf_uri);
1575 ec->is_log_level_set = false;
1580 void ctf_event_class_set_log_level(struct ctf_event_class *ec,
1581 enum bt_event_class_log_level log_level)
1584 ec->log_level = log_level;
1585 ec->is_log_level_set = true;
1589 void ctf_event_class_destroy(struct ctf_event_class *ec)
1596 g_string_free(ec->name, TRUE);
1600 g_string_free(ec->emf_uri, TRUE);
1603 ctf_field_class_destroy(ec->spec_context_fc);
1604 ctf_field_class_destroy(ec->payload_fc);
1609 struct ctf_stream_class *ctf_stream_class_create(void)
1611 struct ctf_stream_class *sc = g_new0(struct ctf_stream_class, 1);
1614 sc->event_classes = g_ptr_array_new_with_free_func(
1615 (GDestroyNotify) ctf_event_class_destroy);
1616 BT_ASSERT(sc->event_classes);
1617 sc->event_classes_by_id = g_hash_table_new(g_direct_hash,
1619 BT_ASSERT(sc->event_classes_by_id);
1624 void ctf_stream_class_destroy(struct ctf_stream_class *sc)
1630 if (sc->event_classes) {
1631 g_ptr_array_free(sc->event_classes, TRUE);
1634 if (sc->event_classes_by_id) {
1635 g_hash_table_destroy(sc->event_classes_by_id);
1638 ctf_field_class_destroy(sc->packet_context_fc);
1639 ctf_field_class_destroy(sc->event_header_fc);
1640 ctf_field_class_destroy(sc->event_common_context_fc);
1645 void ctf_stream_class_append_event_class(struct ctf_stream_class *sc,
1646 struct ctf_event_class *ec)
1648 g_ptr_array_add(sc->event_classes, ec);
1649 g_hash_table_insert(sc->event_classes_by_id,
1650 GUINT_TO_POINTER((guint) ec->id), ec);
1654 struct ctf_event_class *ctf_stream_class_borrow_event_class_by_id(
1655 struct ctf_stream_class *sc, uint64_t type)
1658 return (struct ctf_event_class *) g_hash_table_lookup(sc->event_classes_by_id,
1659 GUINT_TO_POINTER((guint) type));
1663 void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry *entry)
1666 entry->name = g_string_new(NULL);
1667 BT_ASSERT(entry->name);
1668 entry->value.str = g_string_new(NULL);
1669 BT_ASSERT(entry->value.str);
1673 void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry *entry)
1678 g_string_free(entry->name, TRUE);
1681 if (entry->value.str) {
1682 g_string_free(entry->value.str, TRUE);
1687 struct ctf_clock_class *ctf_clock_class_create(void)
1689 struct ctf_clock_class *cc = g_new0(struct ctf_clock_class, 1);
1692 cc->name = g_string_new(NULL);
1693 BT_ASSERT(cc->name);
1694 cc->description = g_string_new(NULL);
1695 BT_ASSERT(cc->description);
1700 void ctf_clock_class_destroy(struct ctf_clock_class *cc)
1707 g_string_free(cc->name, TRUE);
1710 if (cc->description) {
1711 g_string_free(cc->description, TRUE);
1714 bt_clock_class_put_ref(cc->ir_cc);
1719 struct ctf_trace_class *ctf_trace_class_create(void)
1721 struct ctf_trace_class *tc = g_new0(struct ctf_trace_class, 1);
1724 tc->default_byte_order = CTF_BYTE_ORDER_UNKNOWN;
1725 tc->clock_classes = g_ptr_array_new_with_free_func(
1726 (GDestroyNotify) ctf_clock_class_destroy);
1727 BT_ASSERT(tc->clock_classes);
1728 tc->stream_classes = g_ptr_array_new_with_free_func(
1729 (GDestroyNotify) ctf_stream_class_destroy);
1730 BT_ASSERT(tc->stream_classes);
1731 tc->env_entries = g_array_new(FALSE, TRUE,
1732 sizeof(struct ctf_trace_class_env_entry));
1737 void ctf_trace_class_destroy(struct ctf_trace_class *tc)
1743 ctf_field_class_destroy(tc->packet_header_fc);
1745 if (tc->clock_classes) {
1746 g_ptr_array_free(tc->clock_classes, TRUE);
1749 if (tc->stream_classes) {
1750 g_ptr_array_free(tc->stream_classes, TRUE);
1753 if (tc->env_entries) {
1756 for (i = 0; i < tc->env_entries->len; i++) {
1757 struct ctf_trace_class_env_entry *entry =
1758 &g_array_index(tc->env_entries,
1759 struct ctf_trace_class_env_entry, i);
1761 _ctf_trace_class_env_entry_fini(entry);
1764 g_array_free(tc->env_entries, TRUE);
1771 void ctf_trace_class_append_env_entry(struct ctf_trace_class *tc,
1772 const char *name, enum ctf_trace_class_env_entry_type type,
1773 const char *str_value, int64_t i_value)
1775 struct ctf_trace_class_env_entry *entry;
1779 g_array_set_size(tc->env_entries, tc->env_entries->len + 1);
1781 entry = &g_array_index(tc->env_entries,
1782 struct ctf_trace_class_env_entry, tc->env_entries->len - 1);
1784 _ctf_trace_class_env_entry_init(entry);
1785 g_string_assign(entry->name, name);
1788 g_string_assign(entry->value.str, str_value);
1791 entry->value.i = i_value;
1795 struct ctf_stream_class *ctf_trace_class_borrow_stream_class_by_id(
1796 struct ctf_trace_class *tc, uint64_t id)
1799 struct ctf_stream_class *ret_sc = NULL;
1803 for (i = 0; i < tc->stream_classes->len; i++) {
1804 struct ctf_stream_class *sc =
1805 (struct ctf_stream_class *) tc->stream_classes->pdata[i];
1818 struct ctf_clock_class *ctf_trace_class_borrow_clock_class_by_name(
1819 struct ctf_trace_class *tc, const char *name)
1822 struct ctf_clock_class *ret_cc = NULL;
1825 BT_ASSERT_DBG(name);
1827 for (i = 0; i < tc->clock_classes->len; i++) {
1828 struct ctf_clock_class *cc =
1829 (struct ctf_clock_class *) tc->clock_classes->pdata[i];
1831 BT_ASSERT_DBG(cc->name);
1832 if (strcmp(cc->name->str, name) == 0) {
1843 struct ctf_trace_class_env_entry *ctf_trace_class_borrow_env_entry_by_index(
1844 struct ctf_trace_class *tc, uint64_t index)
1847 BT_ASSERT_DBG(index < tc->env_entries->len);
1848 return &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry,
1853 struct ctf_trace_class_env_entry *ctf_trace_class_borrow_env_entry_by_name(
1854 struct ctf_trace_class *tc, const char *name)
1856 struct ctf_trace_class_env_entry *ret_entry = NULL;
1860 BT_ASSERT_DBG(name);
1862 for (i = 0; i < tc->env_entries->len; i++) {
1863 struct ctf_trace_class_env_entry *env_entry =
1864 ctf_trace_class_borrow_env_entry_by_index(tc, i);
1866 if (strcmp(env_entry->name->str, name) == 0) {
1867 ret_entry = env_entry;
1876 #endif /* _CTF_META_H */