2 * SPDX-License-Identifier: MIT
4 * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
14 #include <babeltrace2/babeltrace.h>
16 #include "common/assert.h"
17 #include "common/common.h"
18 #include "common/uuid.h"
19 #include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
21 enum ctf_field_class_type
23 CTF_FIELD_CLASS_TYPE_INT,
24 CTF_FIELD_CLASS_TYPE_ENUM,
25 CTF_FIELD_CLASS_TYPE_FLOAT,
26 CTF_FIELD_CLASS_TYPE_STRING,
27 CTF_FIELD_CLASS_TYPE_STRUCT,
28 CTF_FIELD_CLASS_TYPE_ARRAY,
29 CTF_FIELD_CLASS_TYPE_SEQUENCE,
30 CTF_FIELD_CLASS_TYPE_VARIANT,
33 inline const char *format_as(ctf_field_class_type type) noexcept
36 case CTF_FIELD_CLASS_TYPE_INT:
37 return "CTF_FIELD_CLASS_TYPE_INT";
39 case CTF_FIELD_CLASS_TYPE_ENUM:
40 return "CTF_FIELD_CLASS_TYPE_ENUM";
42 case CTF_FIELD_CLASS_TYPE_FLOAT:
43 return "CTF_FIELD_CLASS_TYPE_FLOAT";
45 case CTF_FIELD_CLASS_TYPE_STRING:
46 return "CTF_FIELD_CLASS_TYPE_STRING";
48 case CTF_FIELD_CLASS_TYPE_STRUCT:
49 return "CTF_FIELD_CLASS_TYPE_STRUCT";
51 case CTF_FIELD_CLASS_TYPE_ARRAY:
52 return "CTF_FIELD_CLASS_TYPE_ARRAY";
54 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
55 return "CTF_FIELD_CLASS_TYPE_SEQUENCE";
57 case CTF_FIELD_CLASS_TYPE_VARIANT:
58 return "CTF_FIELD_CLASS_TYPE_VARIANT";
64 enum ctf_field_class_meaning
66 CTF_FIELD_CLASS_MEANING_NONE,
67 CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME,
68 CTF_FIELD_CLASS_MEANING_PACKET_END_TIME,
69 CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID,
70 CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID,
71 CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID,
72 CTF_FIELD_CLASS_MEANING_MAGIC,
73 CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT,
74 CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT,
75 CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE,
76 CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE,
77 CTF_FIELD_CLASS_MEANING_UUID,
82 CTF_BYTE_ORDER_UNKNOWN,
83 CTF_BYTE_ORDER_DEFAULT,
84 CTF_BYTE_ORDER_LITTLE,
96 CTF_SCOPE_PACKET_UNKNOWN = -1,
97 CTF_SCOPE_PACKET_HEADER = 0,
98 CTF_SCOPE_PACKET_CONTEXT,
99 CTF_SCOPE_EVENT_HEADER,
100 CTF_SCOPE_EVENT_COMMON_CONTEXT,
101 CTF_SCOPE_EVENT_SPECIFIC_CONTEXT,
102 CTF_SCOPE_EVENT_PAYLOAD,
105 inline const char *format_as(const ctf_scope scope) noexcept
108 case CTF_SCOPE_PACKET_UNKNOWN:
109 return "PACKET_UNKNOWN";
111 case CTF_SCOPE_PACKET_HEADER:
112 return "PACKET_HEADER";
114 case CTF_SCOPE_PACKET_CONTEXT:
115 return "PACKET_CONTEXT";
117 case CTF_SCOPE_EVENT_HEADER:
118 return "EVENT_HEADER";
120 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
121 return "EVENT_COMMON_CONTEXT";
123 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
124 return "EVENT_SPECIFIC_CONTEXT";
126 case CTF_SCOPE_EVENT_PAYLOAD:
127 return "EVENT_PAYLOAD";
133 struct ctf_clock_class
136 GString *description;
139 int64_t offset_seconds;
140 uint64_t offset_cycles;
145 /* Weak, set during translation */
146 bt_clock_class *ir_cc;
149 struct ctf_field_class
151 enum ctf_field_class_type type;
152 unsigned int alignment;
156 /* Weak, set during translation. NULL if `in_ir` is false below. */
157 bt_field_class *ir_fc;
160 struct ctf_field_class_bit_array
162 struct ctf_field_class base;
163 enum ctf_byte_order byte_order;
167 struct ctf_field_class_int
169 struct ctf_field_class_bit_array base;
170 enum ctf_field_class_meaning meaning;
172 bt_field_class_integer_preferred_display_base disp_base;
173 enum ctf_encoding encoding;
174 int64_t storing_index;
177 struct ctf_clock_class *mapped_clock_class;
195 struct ctf_field_class_enum_mapping
199 /* Array of `struct ctf_range` */
203 struct ctf_field_class_enum
205 struct ctf_field_class_int base;
207 /* Array of `struct ctf_field_class_enum_mapping` */
211 struct ctf_field_class_float
213 struct ctf_field_class_bit_array base;
216 struct ctf_field_class_string
218 struct ctf_field_class base;
219 enum ctf_encoding encoding;
222 struct ctf_named_field_class
224 /* Original name which can include a leading `_` */
227 /* Name as translated to trace IR (leading `_` removed) */
231 struct ctf_field_class *fc;
234 struct ctf_field_class_struct
236 struct ctf_field_class base;
238 /* Array of `struct ctf_named_field_class` */
242 struct ctf_field_path
246 /* Array of `int64_t` */
250 struct ctf_field_class_variant_range
252 struct ctf_range range;
253 uint64_t option_index;
256 struct ctf_field_class_variant
258 struct ctf_field_class base;
260 struct ctf_field_path tag_path;
261 uint64_t stored_tag_index;
263 /* Array of `struct ctf_named_field_class` */
266 /* Array of `struct ctf_field_class_variant_range` */
270 struct ctf_field_class_enum *tag_fc;
273 struct ctf_field_class_array_base
275 struct ctf_field_class base;
276 struct ctf_field_class *elem_fc;
280 struct ctf_field_class_array
282 struct ctf_field_class_array_base base;
283 enum ctf_field_class_meaning meaning;
287 struct ctf_field_class_sequence
289 struct ctf_field_class_array_base base;
291 struct ctf_field_path length_path;
292 uint64_t stored_length_index;
295 struct ctf_field_class_int *length_fc;
298 struct ctf_event_class
303 bt_event_class_log_level log_level;
305 bool is_log_level_set;
308 struct ctf_field_class *spec_context_fc;
311 struct ctf_field_class *payload_fc;
313 /* Weak, set during translation */
314 bt_event_class *ir_ec;
317 struct ctf_stream_class
321 bool packets_have_ts_begin;
322 bool packets_have_ts_end;
323 bool has_discarded_events;
324 bool has_discarded_packets;
325 bool discarded_events_have_default_cs;
326 bool discarded_packets_have_default_cs;
329 struct ctf_field_class *packet_context_fc;
332 struct ctf_field_class *event_header_fc;
335 struct ctf_field_class *event_common_context_fc;
337 /* Array of `struct ctf_event_class *`, owned by this */
338 GPtrArray *event_classes;
341 * Hash table mapping event class IDs to `struct ctf_event_class *`,
344 GHashTable *event_classes_by_id;
347 struct ctf_clock_class *default_clock_class;
349 /* Weak, set during translation */
350 bt_stream_class *ir_sc;
353 enum ctf_trace_class_env_entry_type
355 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
356 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
359 struct ctf_trace_class_env_entry
361 enum ctf_trace_class_env_entry_type type;
371 struct ctf_trace_class
377 enum ctf_byte_order default_byte_order;
380 struct ctf_field_class *packet_header_fc;
382 uint64_t stored_value_count;
384 /* Array of `struct ctf_clock_class *` (owned by this) */
385 GPtrArray *clock_classes;
387 /* Array of `struct ctf_stream_class *` */
388 GPtrArray *stream_classes;
390 /* Array of `struct ctf_trace_class_env_entry` */
395 /* Weak, set during translation */
396 bt_trace_class *ir_tc;
401 bool lttng_event_after_packet;
402 bool barectf_event_before_packet;
406 static inline ctf_field_class_bit_array *ctf_field_class_as_bit_array(ctf_field_class *fc)
409 (fc->type == CTF_FIELD_CLASS_TYPE_INT || fc->type == CTF_FIELD_CLASS_TYPE_ENUM ||
410 fc->type == CTF_FIELD_CLASS_TYPE_FLOAT));
411 return (ctf_field_class_bit_array *) fc;
414 static inline ctf_field_class_int *ctf_field_class_as_int(ctf_field_class *fc)
417 (fc->type == CTF_FIELD_CLASS_TYPE_INT || fc->type == CTF_FIELD_CLASS_TYPE_ENUM));
418 return (ctf_field_class_int *) fc;
421 static inline ctf_field_class_enum *ctf_field_class_as_enum(ctf_field_class *fc)
423 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ENUM);
424 return (ctf_field_class_enum *) fc;
427 static inline ctf_field_class_float *ctf_field_class_as_float(ctf_field_class *fc)
429 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_FLOAT);
430 return (ctf_field_class_float *) fc;
433 static inline ctf_field_class_string *ctf_field_class_as_string(ctf_field_class *fc)
435 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRING);
436 return (ctf_field_class_string *) fc;
439 static inline ctf_field_class_struct *ctf_field_class_as_struct(ctf_field_class *fc)
441 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRUCT);
442 return (ctf_field_class_struct *) fc;
445 static inline ctf_field_class_array_base *ctf_field_class_as_array_base(ctf_field_class *fc)
447 BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY ||
448 fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE));
449 return (ctf_field_class_array_base *) fc;
452 static inline ctf_field_class_array *ctf_field_class_as_array(ctf_field_class *fc)
454 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ARRAY);
455 return (ctf_field_class_array *) fc;
458 static inline ctf_field_class_sequence *ctf_field_class_as_sequence(ctf_field_class *fc)
460 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE);
461 return (ctf_field_class_sequence *) fc;
464 static inline ctf_field_class_variant *ctf_field_class_as_variant(ctf_field_class *fc)
466 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_VARIANT);
467 return (ctf_field_class_variant *) fc;
470 static inline void ctf_field_class_destroy(struct ctf_field_class *fc);
472 static inline void _ctf_field_class_init(struct ctf_field_class *fc, enum ctf_field_class_type type,
473 unsigned int alignment)
477 fc->alignment = alignment;
481 static inline void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array *fc,
482 enum ctf_field_class_type type)
484 _ctf_field_class_init(&fc->base, type, 1);
487 static inline void _ctf_field_class_int_init(struct ctf_field_class_int *fc,
488 enum ctf_field_class_type type)
490 _ctf_field_class_bit_array_init(&fc->base, type);
491 fc->meaning = CTF_FIELD_CLASS_MEANING_NONE;
492 fc->storing_index = -1;
495 static inline void ctf_field_path_init(struct ctf_field_path *field_path)
497 BT_ASSERT(field_path);
498 field_path->path = g_array_new(FALSE, TRUE, sizeof(int64_t));
499 BT_ASSERT(field_path->path);
502 static inline void ctf_field_path_fini(struct ctf_field_path *field_path)
504 BT_ASSERT(field_path);
506 if (field_path->path) {
507 g_array_free(field_path->path, TRUE);
511 static inline void _ctf_named_field_class_init(struct ctf_named_field_class *named_fc)
514 named_fc->name = g_string_new(NULL);
515 BT_ASSERT(named_fc->name);
516 named_fc->orig_name = g_string_new(NULL);
517 BT_ASSERT(named_fc->orig_name);
520 static inline void _ctf_named_field_class_fini(struct ctf_named_field_class *named_fc)
524 if (named_fc->name) {
525 g_string_free(named_fc->name, TRUE);
528 if (named_fc->orig_name) {
529 g_string_free(named_fc->orig_name, TRUE);
532 ctf_field_class_destroy(named_fc->fc);
535 static inline void _ctf_field_class_enum_mapping_init(struct ctf_field_class_enum_mapping *mapping)
538 mapping->label = g_string_new(NULL);
539 BT_ASSERT(mapping->label);
540 mapping->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_range));
541 BT_ASSERT(mapping->ranges);
544 static inline void _ctf_field_class_enum_mapping_fini(struct ctf_field_class_enum_mapping *mapping)
548 if (mapping->label) {
549 g_string_free(mapping->label, TRUE);
552 if (mapping->ranges) {
553 g_array_free(mapping->ranges, TRUE);
557 static inline struct ctf_field_class_int *ctf_field_class_int_create(void)
559 struct ctf_field_class_int *fc = g_new0(struct ctf_field_class_int, 1);
562 _ctf_field_class_int_init(fc, CTF_FIELD_CLASS_TYPE_INT);
566 static inline struct ctf_field_class_float *ctf_field_class_float_create(void)
568 struct ctf_field_class_float *fc = g_new0(struct ctf_field_class_float, 1);
571 _ctf_field_class_bit_array_init(&fc->base, CTF_FIELD_CLASS_TYPE_FLOAT);
575 static inline struct ctf_field_class_string *ctf_field_class_string_create(void)
577 struct ctf_field_class_string *fc = g_new0(struct ctf_field_class_string, 1);
580 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRING, 8);
584 static inline struct ctf_field_class_enum *ctf_field_class_enum_create(void)
586 struct ctf_field_class_enum *fc = g_new0(struct ctf_field_class_enum, 1);
589 _ctf_field_class_int_init(&fc->base, CTF_FIELD_CLASS_TYPE_ENUM);
590 fc->mappings = g_array_new(FALSE, TRUE, sizeof(struct ctf_field_class_enum_mapping));
591 BT_ASSERT(fc->mappings);
595 static inline struct ctf_field_class_struct *ctf_field_class_struct_create(void)
597 struct ctf_field_class_struct *fc = g_new0(struct ctf_field_class_struct, 1);
600 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRUCT, 1);
601 fc->members = g_array_new(FALSE, TRUE, sizeof(struct ctf_named_field_class));
602 BT_ASSERT(fc->members);
603 fc->base.is_compound = true;
607 static inline struct ctf_field_class_variant *ctf_field_class_variant_create(void)
609 struct ctf_field_class_variant *fc = g_new0(struct ctf_field_class_variant, 1);
612 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_VARIANT, 1);
613 fc->options = g_array_new(FALSE, TRUE, sizeof(struct ctf_named_field_class));
614 BT_ASSERT(fc->options);
615 fc->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_field_class_variant_range));
616 BT_ASSERT(fc->ranges);
617 fc->tag_ref = g_string_new(NULL);
618 BT_ASSERT(fc->tag_ref);
619 ctf_field_path_init(&fc->tag_path);
620 fc->base.is_compound = true;
624 static inline struct ctf_field_class_array *ctf_field_class_array_create(void)
626 struct ctf_field_class_array *fc = g_new0(struct ctf_field_class_array, 1);
629 _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_ARRAY, 1);
630 fc->base.base.is_compound = true;
634 static inline struct ctf_field_class_sequence *ctf_field_class_sequence_create(void)
636 struct ctf_field_class_sequence *fc = g_new0(struct ctf_field_class_sequence, 1);
639 _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_SEQUENCE, 1);
640 fc->length_ref = g_string_new(NULL);
641 BT_ASSERT(fc->length_ref);
642 ctf_field_path_init(&fc->length_path);
643 fc->base.base.is_compound = true;
647 static inline void _ctf_field_class_int_destroy(struct ctf_field_class_int *fc)
653 static inline void _ctf_field_class_enum_destroy(struct ctf_field_class_enum *fc)
660 for (i = 0; i < fc->mappings->len; i++) {
661 struct ctf_field_class_enum_mapping *mapping =
662 &bt_g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, i);
664 _ctf_field_class_enum_mapping_fini(mapping);
667 g_array_free(fc->mappings, TRUE);
673 static inline void _ctf_field_class_float_destroy(struct ctf_field_class_float *fc)
679 static inline void _ctf_field_class_string_destroy(struct ctf_field_class_string *fc)
685 static inline void _ctf_field_class_struct_destroy(struct ctf_field_class_struct *fc)
692 for (i = 0; i < fc->members->len; i++) {
693 struct ctf_named_field_class *named_fc =
694 &bt_g_array_index(fc->members, struct ctf_named_field_class, i);
696 _ctf_named_field_class_fini(named_fc);
699 g_array_free(fc->members, TRUE);
705 static inline void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base *fc)
708 ctf_field_class_destroy(fc->elem_fc);
711 static inline void _ctf_field_class_array_destroy(struct ctf_field_class_array *fc)
714 _ctf_field_class_array_base_fini(&fc->base);
718 static inline void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence *fc)
721 _ctf_field_class_array_base_fini(&fc->base);
723 if (fc->length_ref) {
724 g_string_free(fc->length_ref, TRUE);
727 ctf_field_path_fini(&fc->length_path);
731 static inline void _ctf_field_class_variant_destroy(struct ctf_field_class_variant *fc)
738 for (i = 0; i < fc->options->len; i++) {
739 struct ctf_named_field_class *named_fc =
740 &bt_g_array_index(fc->options, struct ctf_named_field_class, i);
742 _ctf_named_field_class_fini(named_fc);
745 g_array_free(fc->options, TRUE);
749 g_array_free(fc->ranges, TRUE);
753 g_string_free(fc->tag_ref, TRUE);
756 ctf_field_path_fini(&fc->tag_path);
760 static inline void ctf_field_class_destroy(struct ctf_field_class *fc)
767 case CTF_FIELD_CLASS_TYPE_INT:
768 _ctf_field_class_int_destroy(ctf_field_class_as_int(fc));
770 case CTF_FIELD_CLASS_TYPE_ENUM:
771 _ctf_field_class_enum_destroy(ctf_field_class_as_enum(fc));
773 case CTF_FIELD_CLASS_TYPE_FLOAT:
774 _ctf_field_class_float_destroy(ctf_field_class_as_float(fc));
776 case CTF_FIELD_CLASS_TYPE_STRING:
777 _ctf_field_class_string_destroy(ctf_field_class_as_string(fc));
779 case CTF_FIELD_CLASS_TYPE_STRUCT:
780 _ctf_field_class_struct_destroy(ctf_field_class_as_struct(fc));
782 case CTF_FIELD_CLASS_TYPE_ARRAY:
783 _ctf_field_class_array_destroy(ctf_field_class_as_array(fc));
785 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
786 _ctf_field_class_sequence_destroy(ctf_field_class_as_sequence(fc));
788 case CTF_FIELD_CLASS_TYPE_VARIANT:
789 _ctf_field_class_variant_destroy(ctf_field_class_as_variant(fc));
796 static inline struct ctf_range *
797 ctf_field_class_enum_mapping_borrow_range_by_index(struct ctf_field_class_enum_mapping *mapping,
800 BT_ASSERT_DBG(mapping);
801 BT_ASSERT_DBG(index < mapping->ranges->len);
802 return &bt_g_array_index(mapping->ranges, struct ctf_range, index);
805 static inline struct ctf_field_class_enum_mapping *
806 ctf_field_class_enum_borrow_mapping_by_index(struct ctf_field_class_enum *fc, uint64_t index)
809 BT_ASSERT_DBG(index < fc->mappings->len);
810 return &bt_g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, index);
813 static inline struct ctf_field_class_enum_mapping *
814 ctf_field_class_enum_borrow_mapping_by_label(struct ctf_field_class_enum *fc, const char *label)
816 struct ctf_field_class_enum_mapping *ret_mapping = NULL;
820 BT_ASSERT_DBG(label);
822 for (i = 0; i < fc->mappings->len; i++) {
823 struct ctf_field_class_enum_mapping *mapping =
824 ctf_field_class_enum_borrow_mapping_by_index(fc, i);
826 if (strcmp(mapping->label->str, label) == 0) {
827 ret_mapping = mapping;
836 static inline void ctf_field_class_enum_map_range(struct ctf_field_class_enum *fc,
837 const char *label, uint64_t u_lower,
840 struct ctf_field_class_enum_mapping *mapping = NULL;
841 struct ctf_range range = {
856 for (i = 0; i < fc->mappings->len; i++) {
857 mapping = ctf_field_class_enum_borrow_mapping_by_index(fc, i);
859 if (strcmp(mapping->label->str, label) == 0) {
864 if (i == fc->mappings->len) {
869 g_array_set_size(fc->mappings, fc->mappings->len + 1);
870 mapping = ctf_field_class_enum_borrow_mapping_by_index(fc, fc->mappings->len - 1);
871 _ctf_field_class_enum_mapping_init(mapping);
872 g_string_assign(mapping->label, label);
875 g_array_append_val(mapping->ranges, range);
878 static inline struct ctf_named_field_class *
879 ctf_field_class_struct_borrow_member_by_index(struct ctf_field_class_struct *fc, uint64_t index)
882 BT_ASSERT_DBG(index < fc->members->len);
883 return &bt_g_array_index(fc->members, struct ctf_named_field_class, index);
886 static inline struct ctf_named_field_class *
887 ctf_field_class_struct_borrow_member_by_name(struct ctf_field_class_struct *fc, const char *name)
890 struct ctf_named_field_class *ret_named_fc = NULL;
895 for (i = 0; i < fc->members->len; i++) {
896 struct ctf_named_field_class *named_fc =
897 ctf_field_class_struct_borrow_member_by_index(fc, i);
899 if (strcmp(name, named_fc->name->str) == 0) {
900 ret_named_fc = named_fc;
909 static inline struct ctf_field_class *
910 ctf_field_class_struct_borrow_member_field_class_by_name(struct ctf_field_class_struct *struct_fc,
913 struct ctf_named_field_class *named_fc = NULL;
914 struct ctf_field_class *fc = NULL;
920 named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name);
931 static inline struct ctf_field_class_int *
932 ctf_field_class_struct_borrow_member_int_field_class_by_name(
933 struct ctf_field_class_struct *struct_fc, const char *name)
935 ctf_field_class *member_fc =
936 ctf_field_class_struct_borrow_member_field_class_by_name(struct_fc, name);
942 if (member_fc->type != CTF_FIELD_CLASS_TYPE_INT &&
943 member_fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
947 return ctf_field_class_as_int(member_fc);
950 static inline void _ctf_named_field_class_unescape_orig_name(struct ctf_named_field_class *named_fc)
952 const char *name = named_fc->orig_name->str;
954 if (name[0] == '_') {
958 g_string_assign(named_fc->name, name);
961 static inline void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc,
962 const char *orig_name,
963 struct ctf_field_class *member_fc)
965 struct ctf_named_field_class *named_fc;
968 BT_ASSERT(orig_name);
969 g_array_set_size(fc->members, fc->members->len + 1);
971 named_fc = &bt_g_array_index(fc->members, struct ctf_named_field_class, fc->members->len - 1);
972 _ctf_named_field_class_init(named_fc);
973 g_string_assign(named_fc->orig_name, orig_name);
974 _ctf_named_field_class_unescape_orig_name(named_fc);
975 named_fc->fc = member_fc;
977 if (member_fc->alignment > fc->base.alignment) {
978 fc->base.alignment = member_fc->alignment;
982 static inline struct ctf_named_field_class *
983 ctf_field_class_variant_borrow_option_by_index(struct ctf_field_class_variant *fc, uint64_t index)
986 BT_ASSERT_DBG(index < fc->options->len);
987 return &bt_g_array_index(fc->options, struct ctf_named_field_class, index);
990 static inline struct ctf_named_field_class *
991 ctf_field_class_variant_borrow_option_by_name(struct ctf_field_class_variant *fc, const char *name)
994 struct ctf_named_field_class *ret_named_fc = NULL;
999 for (i = 0; i < fc->options->len; i++) {
1000 struct ctf_named_field_class *named_fc =
1001 ctf_field_class_variant_borrow_option_by_index(fc, i);
1003 if (strcmp(name, named_fc->name->str) == 0) {
1004 ret_named_fc = named_fc;
1010 return ret_named_fc;
1013 static inline struct ctf_field_class_variant_range *
1014 ctf_field_class_variant_borrow_range_by_index(struct ctf_field_class_variant *fc, uint64_t index)
1017 BT_ASSERT_DBG(index < fc->ranges->len);
1018 return &bt_g_array_index(fc->ranges, struct ctf_field_class_variant_range, index);
1021 static inline void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc,
1022 const char *orig_name,
1023 struct ctf_field_class *option_fc)
1025 struct ctf_named_field_class *named_fc;
1028 BT_ASSERT(orig_name);
1029 g_array_set_size(fc->options, fc->options->len + 1);
1031 named_fc = &bt_g_array_index(fc->options, struct ctf_named_field_class, fc->options->len - 1);
1032 _ctf_named_field_class_init(named_fc);
1033 g_string_assign(named_fc->orig_name, orig_name);
1034 _ctf_named_field_class_unescape_orig_name(named_fc);
1035 named_fc->fc = option_fc;
1038 static inline void ctf_field_class_variant_set_tag_field_class(struct ctf_field_class_variant *fc,
1039 struct ctf_field_class_enum *tag_fc)
1045 fc->tag_fc = tag_fc;
1047 for (option_i = 0; option_i < fc->options->len; option_i++) {
1049 struct ctf_named_field_class *named_fc =
1050 ctf_field_class_variant_borrow_option_by_index(fc, option_i);
1051 struct ctf_field_class_enum_mapping *mapping;
1053 mapping = ctf_field_class_enum_borrow_mapping_by_label(tag_fc, named_fc->orig_name->str);
1058 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
1059 struct ctf_range *range =
1060 ctf_field_class_enum_mapping_borrow_range_by_index(mapping, range_i);
1061 struct ctf_field_class_variant_range var_range;
1063 var_range.range = *range;
1064 var_range.option_index = option_i;
1065 g_array_append_val(fc->ranges, var_range);
1070 static inline struct ctf_field_class *
1071 ctf_field_class_compound_borrow_field_class_by_index(struct ctf_field_class *comp_fc,
1074 struct ctf_field_class *fc = NULL;
1076 switch (comp_fc->type) {
1077 case CTF_FIELD_CLASS_TYPE_STRUCT:
1079 struct ctf_named_field_class *named_fc = ctf_field_class_struct_borrow_member_by_index(
1080 (struct ctf_field_class_struct *) comp_fc, index);
1082 BT_ASSERT_DBG(named_fc);
1086 case CTF_FIELD_CLASS_TYPE_VARIANT:
1088 struct ctf_named_field_class *named_fc = ctf_field_class_variant_borrow_option_by_index(
1089 (struct ctf_field_class_variant *) comp_fc, index);
1091 BT_ASSERT_DBG(named_fc);
1095 case CTF_FIELD_CLASS_TYPE_ARRAY:
1096 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1098 struct ctf_field_class_array_base *array_fc = (struct ctf_field_class_array_base *) comp_fc;
1100 fc = array_fc->elem_fc;
1110 static inline uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class *fc)
1112 uint64_t field_count;
1115 case CTF_FIELD_CLASS_TYPE_STRUCT:
1117 struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc;
1119 field_count = struct_fc->members->len;
1122 case CTF_FIELD_CLASS_TYPE_VARIANT:
1124 struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc;
1126 field_count = var_fc->options->len;
1129 case CTF_FIELD_CLASS_TYPE_ARRAY:
1130 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1132 * Array and sequence types always contain a single
1133 * member (the element type).
1144 static inline int64_t
1145 ctf_field_class_compound_get_field_class_index_from_orig_name(struct ctf_field_class *fc,
1146 const char *orig_name)
1148 int64_t ret_index = -1;
1152 case CTF_FIELD_CLASS_TYPE_STRUCT:
1154 struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc;
1156 for (i = 0; i < struct_fc->members->len; i++) {
1157 struct ctf_named_field_class *named_fc =
1158 ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
1160 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1161 ret_index = (int64_t) i;
1168 case CTF_FIELD_CLASS_TYPE_VARIANT:
1170 struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc;
1172 for (i = 0; i < var_fc->options->len; i++) {
1173 struct ctf_named_field_class *named_fc =
1174 ctf_field_class_variant_borrow_option_by_index(var_fc, i);
1176 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1177 ret_index = (int64_t) i;
1192 static inline void ctf_field_path_append_index(struct ctf_field_path *fp, int64_t index)
1195 g_array_append_val(fp->path, index);
1198 static inline int64_t ctf_field_path_borrow_index_by_index(const ctf_field_path *fp, uint64_t index)
1201 BT_ASSERT_DBG(index < fp->path->len);
1202 return bt_g_array_index(fp->path, int64_t, index);
1205 static inline void ctf_field_path_clear(struct ctf_field_path *fp)
1208 g_array_set_size(fp->path, 0);
1211 inline std::string format_as(const ctf_field_path& path)
1213 std::string str = fmt::format("[{}", path.root);
1215 for (guint i = 0; i < path.path->len; i++) {
1216 str += fmt::format(", {}", ctf_field_path_borrow_index_by_index(&path, i));
1223 static inline struct ctf_field_class *
1224 ctf_field_path_borrow_field_class(struct ctf_field_path *field_path, struct ctf_trace_class *tc,
1225 struct ctf_stream_class *sc, struct ctf_event_class *ec)
1228 struct ctf_field_class *fc;
1230 switch (field_path->root) {
1231 case CTF_SCOPE_PACKET_HEADER:
1232 fc = tc->packet_header_fc;
1234 case CTF_SCOPE_PACKET_CONTEXT:
1235 fc = sc->packet_context_fc;
1237 case CTF_SCOPE_EVENT_HEADER:
1238 fc = sc->event_header_fc;
1240 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1241 fc = sc->event_common_context_fc;
1243 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1244 fc = ec->spec_context_fc;
1246 case CTF_SCOPE_EVENT_PAYLOAD:
1247 fc = ec->payload_fc;
1255 for (i = 0; i < field_path->path->len; i++) {
1256 int64_t child_index = ctf_field_path_borrow_index_by_index(field_path, i);
1257 struct ctf_field_class *child_fc =
1258 ctf_field_class_compound_borrow_field_class_by_index(fc, child_index);
1259 BT_ASSERT_DBG(child_fc);
1267 static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc);
1269 static inline void ctf_field_class_bit_array_copy_content(struct ctf_field_class_bit_array *dst_fc,
1270 struct ctf_field_class_bit_array *src_fc)
1274 dst_fc->byte_order = src_fc->byte_order;
1275 dst_fc->size = src_fc->size;
1278 static inline void ctf_field_class_int_copy_content(struct ctf_field_class_int *dst_fc,
1279 struct ctf_field_class_int *src_fc)
1281 ctf_field_class_bit_array_copy_content(&dst_fc->base, &src_fc->base);
1282 dst_fc->meaning = src_fc->meaning;
1283 dst_fc->is_signed = src_fc->is_signed;
1284 dst_fc->disp_base = src_fc->disp_base;
1285 dst_fc->encoding = src_fc->encoding;
1286 dst_fc->mapped_clock_class = src_fc->mapped_clock_class;
1287 dst_fc->storing_index = src_fc->storing_index;
1290 static inline struct ctf_field_class_int *_ctf_field_class_int_copy(struct ctf_field_class_int *fc)
1292 struct ctf_field_class_int *copy_fc = ctf_field_class_int_create();
1295 ctf_field_class_int_copy_content(copy_fc, fc);
1299 static inline struct ctf_field_class_enum *
1300 _ctf_field_class_enum_copy(struct ctf_field_class_enum *fc)
1302 struct ctf_field_class_enum *copy_fc = ctf_field_class_enum_create();
1306 ctf_field_class_int_copy_content(©_fc->base, &fc->base);
1308 for (i = 0; i < fc->mappings->len; i++) {
1311 struct ctf_field_class_enum_mapping *mapping =
1312 &bt_g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, i);
1314 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
1315 struct ctf_range *range = &bt_g_array_index(mapping->ranges, struct ctf_range, range_i);
1317 ctf_field_class_enum_map_range(copy_fc, mapping->label->str, range->lower.u,
1325 static inline struct ctf_field_class_float *
1326 _ctf_field_class_float_copy(struct ctf_field_class_float *fc)
1328 struct ctf_field_class_float *copy_fc = ctf_field_class_float_create();
1331 ctf_field_class_bit_array_copy_content(©_fc->base, &fc->base);
1335 static inline struct ctf_field_class_string *
1336 _ctf_field_class_string_copy(struct ctf_field_class_string *)
1338 struct ctf_field_class_string *copy_fc = ctf_field_class_string_create();
1344 static inline struct ctf_field_class_struct *
1345 _ctf_field_class_struct_copy(struct ctf_field_class_struct *fc)
1347 struct ctf_field_class_struct *copy_fc = ctf_field_class_struct_create();
1352 for (i = 0; i < fc->members->len; i++) {
1353 struct ctf_named_field_class *named_fc =
1354 &bt_g_array_index(fc->members, struct ctf_named_field_class, i);
1356 ctf_field_class_struct_append_member(copy_fc, named_fc->name->str,
1357 ctf_field_class_copy(named_fc->fc));
1363 static inline void ctf_field_path_copy_content(struct ctf_field_path *dst_fp,
1364 struct ctf_field_path *src_fp)
1370 dst_fp->root = src_fp->root;
1371 ctf_field_path_clear(dst_fp);
1373 for (i = 0; i < src_fp->path->len; i++) {
1374 int64_t index = ctf_field_path_borrow_index_by_index(src_fp, i);
1376 ctf_field_path_append_index(dst_fp, index);
1380 static inline struct ctf_field_class_variant *
1381 _ctf_field_class_variant_copy(struct ctf_field_class_variant *fc)
1383 struct ctf_field_class_variant *copy_fc = ctf_field_class_variant_create();
1388 for (i = 0; i < fc->options->len; i++) {
1389 struct ctf_named_field_class *named_fc =
1390 &bt_g_array_index(fc->options, struct ctf_named_field_class, i);
1392 ctf_field_class_variant_append_option(copy_fc, named_fc->name->str,
1393 ctf_field_class_copy(named_fc->fc));
1396 for (i = 0; i < fc->ranges->len; i++) {
1397 struct ctf_field_class_variant_range *range =
1398 &bt_g_array_index(fc->ranges, struct ctf_field_class_variant_range, i);
1400 g_array_append_val(copy_fc->ranges, *range);
1403 ctf_field_path_copy_content(©_fc->tag_path, &fc->tag_path);
1404 g_string_assign(copy_fc->tag_ref, fc->tag_ref->str);
1405 copy_fc->stored_tag_index = fc->stored_tag_index;
1410 ctf_field_class_array_base_copy_content(struct ctf_field_class_array_base *dst_fc,
1411 struct ctf_field_class_array_base *src_fc)
1415 dst_fc->elem_fc = ctf_field_class_copy(src_fc->elem_fc);
1416 dst_fc->is_text = src_fc->is_text;
1419 static inline struct ctf_field_class_array *
1420 _ctf_field_class_array_copy(struct ctf_field_class_array *fc)
1422 struct ctf_field_class_array *copy_fc = ctf_field_class_array_create();
1425 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1426 copy_fc->length = fc->length;
1430 static inline struct ctf_field_class_sequence *
1431 _ctf_field_class_sequence_copy(struct ctf_field_class_sequence *fc)
1433 struct ctf_field_class_sequence *copy_fc = ctf_field_class_sequence_create();
1436 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1437 ctf_field_path_copy_content(©_fc->length_path, &fc->length_path);
1438 g_string_assign(copy_fc->length_ref, fc->length_ref->str);
1439 copy_fc->stored_length_index = fc->stored_length_index;
1443 static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc)
1445 struct ctf_field_class *copy_fc = NULL;
1452 * Translation should not have happened yet.
1454 BT_ASSERT(!fc->ir_fc);
1457 case CTF_FIELD_CLASS_TYPE_INT:
1458 copy_fc = &_ctf_field_class_int_copy(ctf_field_class_as_int(fc))->base.base;
1460 case CTF_FIELD_CLASS_TYPE_ENUM:
1461 copy_fc = &_ctf_field_class_enum_copy(ctf_field_class_as_enum(fc))->base.base.base;
1463 case CTF_FIELD_CLASS_TYPE_FLOAT:
1464 copy_fc = &_ctf_field_class_float_copy(ctf_field_class_as_float(fc))->base.base;
1466 case CTF_FIELD_CLASS_TYPE_STRING:
1467 copy_fc = &_ctf_field_class_string_copy(ctf_field_class_as_string(fc))->base;
1469 case CTF_FIELD_CLASS_TYPE_STRUCT:
1470 copy_fc = &_ctf_field_class_struct_copy(ctf_field_class_as_struct(fc))->base;
1472 case CTF_FIELD_CLASS_TYPE_ARRAY:
1473 copy_fc = &_ctf_field_class_array_copy(ctf_field_class_as_array(fc))->base.base;
1475 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1476 copy_fc = &_ctf_field_class_sequence_copy(ctf_field_class_as_sequence(fc))->base.base;
1478 case CTF_FIELD_CLASS_TYPE_VARIANT:
1479 copy_fc = &_ctf_field_class_variant_copy(ctf_field_class_as_variant(fc))->base;
1485 copy_fc->type = fc->type;
1486 copy_fc->alignment = fc->alignment;
1487 copy_fc->in_ir = fc->in_ir;
1493 static inline struct ctf_event_class *ctf_event_class_create(void)
1495 struct ctf_event_class *ec = g_new0(struct ctf_event_class, 1);
1498 ec->name = g_string_new(NULL);
1499 BT_ASSERT(ec->name);
1500 ec->emf_uri = g_string_new(NULL);
1501 BT_ASSERT(ec->emf_uri);
1502 ec->is_log_level_set = false;
1506 static inline void ctf_event_class_set_log_level(struct ctf_event_class *ec,
1507 enum bt_event_class_log_level log_level)
1510 ec->log_level = log_level;
1511 ec->is_log_level_set = true;
1514 static inline void ctf_event_class_destroy(struct ctf_event_class *ec)
1521 g_string_free(ec->name, TRUE);
1525 g_string_free(ec->emf_uri, TRUE);
1528 ctf_field_class_destroy(ec->spec_context_fc);
1529 ctf_field_class_destroy(ec->payload_fc);
1533 static inline struct ctf_stream_class *ctf_stream_class_create(void)
1535 struct ctf_stream_class *sc = g_new0(struct ctf_stream_class, 1);
1538 sc->event_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_event_class_destroy);
1539 BT_ASSERT(sc->event_classes);
1540 sc->event_classes_by_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1541 BT_ASSERT(sc->event_classes_by_id);
1545 static inline void ctf_stream_class_destroy(struct ctf_stream_class *sc)
1551 if (sc->event_classes) {
1552 g_ptr_array_free(sc->event_classes, TRUE);
1555 if (sc->event_classes_by_id) {
1556 g_hash_table_destroy(sc->event_classes_by_id);
1559 ctf_field_class_destroy(sc->packet_context_fc);
1560 ctf_field_class_destroy(sc->event_header_fc);
1561 ctf_field_class_destroy(sc->event_common_context_fc);
1565 static inline void ctf_stream_class_append_event_class(struct ctf_stream_class *sc,
1566 struct ctf_event_class *ec)
1568 g_ptr_array_add(sc->event_classes, ec);
1569 g_hash_table_insert(sc->event_classes_by_id, GUINT_TO_POINTER((guint) ec->id), ec);
1572 static inline struct ctf_event_class *
1573 ctf_stream_class_borrow_event_class_by_id(struct ctf_stream_class *sc, uint64_t type)
1576 return (struct ctf_event_class *) g_hash_table_lookup(sc->event_classes_by_id,
1577 GUINT_TO_POINTER((guint) type));
1580 static inline void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry *entry)
1583 entry->name = g_string_new(NULL);
1584 BT_ASSERT(entry->name);
1585 entry->value.str = g_string_new(NULL);
1586 BT_ASSERT(entry->value.str);
1589 static inline void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry *entry)
1594 g_string_free(entry->name, TRUE);
1597 if (entry->value.str) {
1598 g_string_free(entry->value.str, TRUE);
1602 static inline struct ctf_clock_class *ctf_clock_class_create(void)
1604 struct ctf_clock_class *cc = g_new0(struct ctf_clock_class, 1);
1607 cc->name = g_string_new(NULL);
1608 BT_ASSERT(cc->name);
1609 cc->description = g_string_new(NULL);
1610 BT_ASSERT(cc->description);
1614 static inline void ctf_clock_class_destroy(struct ctf_clock_class *cc)
1621 g_string_free(cc->name, TRUE);
1624 if (cc->description) {
1625 g_string_free(cc->description, TRUE);
1628 bt_clock_class_put_ref(cc->ir_cc);
1632 static inline struct ctf_trace_class *ctf_trace_class_create(void)
1634 struct ctf_trace_class *tc = g_new0(struct ctf_trace_class, 1);
1637 tc->default_byte_order = CTF_BYTE_ORDER_UNKNOWN;
1638 tc->clock_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_clock_class_destroy);
1639 BT_ASSERT(tc->clock_classes);
1640 tc->stream_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_stream_class_destroy);
1641 BT_ASSERT(tc->stream_classes);
1642 tc->env_entries = g_array_new(FALSE, TRUE, sizeof(struct ctf_trace_class_env_entry));
1646 static inline void ctf_trace_class_destroy(struct ctf_trace_class *tc)
1652 ctf_field_class_destroy(tc->packet_header_fc);
1654 if (tc->clock_classes) {
1655 g_ptr_array_free(tc->clock_classes, TRUE);
1658 if (tc->stream_classes) {
1659 g_ptr_array_free(tc->stream_classes, TRUE);
1662 if (tc->env_entries) {
1665 for (i = 0; i < tc->env_entries->len; i++) {
1666 struct ctf_trace_class_env_entry *entry =
1667 &bt_g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, i);
1669 _ctf_trace_class_env_entry_fini(entry);
1672 g_array_free(tc->env_entries, TRUE);
1678 static inline void ctf_trace_class_append_env_entry(struct ctf_trace_class *tc, const char *name,
1679 enum ctf_trace_class_env_entry_type type,
1680 const char *str_value, int64_t i_value)
1682 struct ctf_trace_class_env_entry *entry;
1686 g_array_set_size(tc->env_entries, tc->env_entries->len + 1);
1688 entry = &bt_g_array_index(tc->env_entries, struct ctf_trace_class_env_entry,
1689 tc->env_entries->len - 1);
1691 _ctf_trace_class_env_entry_init(entry);
1692 g_string_assign(entry->name, name);
1695 g_string_assign(entry->value.str, str_value);
1698 entry->value.i = i_value;
1701 static inline struct ctf_stream_class *
1702 ctf_trace_class_borrow_stream_class_by_id(struct ctf_trace_class *tc, uint64_t id)
1705 struct ctf_stream_class *ret_sc = NULL;
1709 for (i = 0; i < tc->stream_classes->len; i++) {
1710 struct ctf_stream_class *sc = (struct ctf_stream_class *) tc->stream_classes->pdata[i];
1722 static inline struct ctf_clock_class *
1723 ctf_trace_class_borrow_clock_class_by_name(struct ctf_trace_class *tc, const char *name)
1726 struct ctf_clock_class *ret_cc = NULL;
1729 BT_ASSERT_DBG(name);
1731 for (i = 0; i < tc->clock_classes->len; i++) {
1732 struct ctf_clock_class *cc = (struct ctf_clock_class *) tc->clock_classes->pdata[i];
1734 BT_ASSERT_DBG(cc->name);
1735 if (strcmp(cc->name->str, name) == 0) {
1745 static inline struct ctf_trace_class_env_entry *
1746 ctf_trace_class_borrow_env_entry_by_index(struct ctf_trace_class *tc, uint64_t index)
1749 BT_ASSERT_DBG(index < tc->env_entries->len);
1750 return &bt_g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, index);
1753 static inline struct ctf_trace_class_env_entry *
1754 ctf_trace_class_borrow_env_entry_by_name(struct ctf_trace_class *tc, const char *name)
1756 struct ctf_trace_class_env_entry *ret_entry = NULL;
1760 BT_ASSERT_DBG(name);
1762 for (i = 0; i < tc->env_entries->len; i++) {
1763 struct ctf_trace_class_env_entry *env_entry =
1764 ctf_trace_class_borrow_env_entry_by_index(tc, i);
1766 if (strcmp(env_entry->name->str, name) == 0) {
1767 ret_entry = env_entry;
1776 #endif /* _CTF_META_H */