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
21 CTF_FIELD_CLASS_TYPE_INT,
22 CTF_FIELD_CLASS_TYPE_ENUM,
23 CTF_FIELD_CLASS_TYPE_FLOAT,
24 CTF_FIELD_CLASS_TYPE_STRING,
25 CTF_FIELD_CLASS_TYPE_STRUCT,
26 CTF_FIELD_CLASS_TYPE_ARRAY,
27 CTF_FIELD_CLASS_TYPE_SEQUENCE,
28 CTF_FIELD_CLASS_TYPE_VARIANT,
31 enum ctf_field_class_meaning
33 CTF_FIELD_CLASS_MEANING_NONE,
34 CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME,
35 CTF_FIELD_CLASS_MEANING_PACKET_END_TIME,
36 CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID,
37 CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID,
38 CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID,
39 CTF_FIELD_CLASS_MEANING_MAGIC,
40 CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT,
41 CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT,
42 CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE,
43 CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE,
44 CTF_FIELD_CLASS_MEANING_UUID,
49 CTF_BYTE_ORDER_UNKNOWN,
50 CTF_BYTE_ORDER_DEFAULT,
51 CTF_BYTE_ORDER_LITTLE,
63 CTF_SCOPE_PACKET_UNKNOWN = -1,
64 CTF_SCOPE_PACKET_HEADER = 0,
65 CTF_SCOPE_PACKET_CONTEXT,
66 CTF_SCOPE_EVENT_HEADER,
67 CTF_SCOPE_EVENT_COMMON_CONTEXT,
68 CTF_SCOPE_EVENT_SPECIFIC_CONTEXT,
69 CTF_SCOPE_EVENT_PAYLOAD,
72 struct ctf_clock_class
78 int64_t offset_seconds;
79 uint64_t offset_cycles;
84 /* Weak, set during translation */
85 bt_clock_class *ir_cc;
88 struct ctf_field_class
90 enum ctf_field_class_type type;
91 unsigned int alignment;
95 /* Weak, set during translation. NULL if `in_ir` is false below. */
96 bt_field_class *ir_fc;
99 struct ctf_field_class_bit_array
101 struct ctf_field_class base;
102 enum ctf_byte_order byte_order;
106 struct ctf_field_class_int
108 struct ctf_field_class_bit_array base;
109 enum ctf_field_class_meaning meaning;
111 bt_field_class_integer_preferred_display_base disp_base;
112 enum ctf_encoding encoding;
113 int64_t storing_index;
116 struct ctf_clock_class *mapped_clock_class;
134 struct ctf_field_class_enum_mapping
138 /* Array of `struct ctf_range` */
142 struct ctf_field_class_enum
144 struct ctf_field_class_int base;
146 /* Array of `struct ctf_field_class_enum_mapping` */
150 struct ctf_field_class_float
152 struct ctf_field_class_bit_array base;
155 struct ctf_field_class_string
157 struct ctf_field_class base;
158 enum ctf_encoding encoding;
161 struct ctf_named_field_class
163 /* Original name which can include a leading `_` */
166 /* Name as translated to trace IR (leading `_` removed) */
170 struct ctf_field_class *fc;
173 struct ctf_field_class_struct
175 struct ctf_field_class base;
177 /* Array of `struct ctf_named_field_class` */
181 struct ctf_field_path
185 /* Array of `int64_t` */
189 struct ctf_field_class_variant_range
191 struct ctf_range range;
192 uint64_t option_index;
195 struct ctf_field_class_variant
197 struct ctf_field_class base;
199 struct ctf_field_path tag_path;
200 uint64_t stored_tag_index;
202 /* Array of `struct ctf_named_field_class` */
205 /* Array of `struct ctf_field_class_variant_range` */
209 struct ctf_field_class_enum *tag_fc;
212 struct ctf_field_class_array_base
214 struct ctf_field_class base;
215 struct ctf_field_class *elem_fc;
219 struct ctf_field_class_array
221 struct ctf_field_class_array_base base;
222 enum ctf_field_class_meaning meaning;
226 struct ctf_field_class_sequence
228 struct ctf_field_class_array_base base;
230 struct ctf_field_path length_path;
231 uint64_t stored_length_index;
234 struct ctf_field_class_int *length_fc;
237 struct ctf_event_class
242 bt_event_class_log_level log_level;
244 bool is_log_level_set;
247 struct ctf_field_class *spec_context_fc;
250 struct ctf_field_class *payload_fc;
252 /* Weak, set during translation */
253 bt_event_class *ir_ec;
256 struct ctf_stream_class
260 bool packets_have_ts_begin;
261 bool packets_have_ts_end;
262 bool has_discarded_events;
263 bool has_discarded_packets;
264 bool discarded_events_have_default_cs;
265 bool discarded_packets_have_default_cs;
268 struct ctf_field_class *packet_context_fc;
271 struct ctf_field_class *event_header_fc;
274 struct ctf_field_class *event_common_context_fc;
276 /* Array of `struct ctf_event_class *`, owned by this */
277 GPtrArray *event_classes;
280 * Hash table mapping event class IDs to `struct ctf_event_class *`,
283 GHashTable *event_classes_by_id;
286 struct ctf_clock_class *default_clock_class;
288 /* Weak, set during translation */
289 bt_stream_class *ir_sc;
292 enum ctf_trace_class_env_entry_type
294 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
295 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
298 struct ctf_trace_class_env_entry
300 enum ctf_trace_class_env_entry_type type;
310 struct ctf_trace_class
316 enum ctf_byte_order default_byte_order;
319 struct ctf_field_class *packet_header_fc;
321 uint64_t stored_value_count;
323 /* Array of `struct ctf_clock_class *` (owned by this) */
324 GPtrArray *clock_classes;
326 /* Array of `struct ctf_stream_class *` */
327 GPtrArray *stream_classes;
329 /* Array of `struct ctf_trace_class_env_entry` */
334 /* Weak, set during translation */
335 bt_trace_class *ir_tc;
340 bool lttng_event_after_packet;
341 bool barectf_event_before_packet;
345 static inline ctf_field_class_bit_array *ctf_field_class_as_bit_array(ctf_field_class *fc)
348 (fc->type == CTF_FIELD_CLASS_TYPE_INT || fc->type == CTF_FIELD_CLASS_TYPE_ENUM ||
349 fc->type == CTF_FIELD_CLASS_TYPE_FLOAT));
350 return (ctf_field_class_bit_array *) fc;
353 static inline ctf_field_class_int *ctf_field_class_as_int(ctf_field_class *fc)
356 (fc->type == CTF_FIELD_CLASS_TYPE_INT || fc->type == CTF_FIELD_CLASS_TYPE_ENUM));
357 return (ctf_field_class_int *) fc;
360 static inline ctf_field_class_enum *ctf_field_class_as_enum(ctf_field_class *fc)
362 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ENUM);
363 return (ctf_field_class_enum *) fc;
366 static inline ctf_field_class_float *ctf_field_class_as_float(ctf_field_class *fc)
368 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_FLOAT);
369 return (ctf_field_class_float *) fc;
372 static inline ctf_field_class_string *ctf_field_class_as_string(ctf_field_class *fc)
374 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRING);
375 return (ctf_field_class_string *) fc;
378 static inline ctf_field_class_struct *ctf_field_class_as_struct(ctf_field_class *fc)
380 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_STRUCT);
381 return (ctf_field_class_struct *) fc;
384 static inline ctf_field_class_array_base *ctf_field_class_as_array_base(ctf_field_class *fc)
386 BT_ASSERT_DBG(!fc || (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY ||
387 fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE));
388 return (ctf_field_class_array_base *) fc;
391 static inline ctf_field_class_array *ctf_field_class_as_array(ctf_field_class *fc)
393 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_ARRAY);
394 return (ctf_field_class_array *) fc;
397 static inline ctf_field_class_sequence *ctf_field_class_as_sequence(ctf_field_class *fc)
399 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE);
400 return (ctf_field_class_sequence *) fc;
403 static inline ctf_field_class_variant *ctf_field_class_as_variant(ctf_field_class *fc)
405 BT_ASSERT_DBG(!fc || fc->type == CTF_FIELD_CLASS_TYPE_VARIANT);
406 return (ctf_field_class_variant *) fc;
409 static inline void ctf_field_class_destroy(struct ctf_field_class *fc);
411 static inline void _ctf_field_class_init(struct ctf_field_class *fc, enum ctf_field_class_type type,
412 unsigned int alignment)
416 fc->alignment = alignment;
420 static inline void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array *fc,
421 enum ctf_field_class_type type)
423 _ctf_field_class_init(&fc->base, type, 1);
426 static inline void _ctf_field_class_int_init(struct ctf_field_class_int *fc,
427 enum ctf_field_class_type type)
429 _ctf_field_class_bit_array_init(&fc->base, type);
430 fc->meaning = CTF_FIELD_CLASS_MEANING_NONE;
431 fc->storing_index = -1;
434 static inline void ctf_field_path_init(struct ctf_field_path *field_path)
436 BT_ASSERT(field_path);
437 field_path->path = g_array_new(FALSE, TRUE, sizeof(int64_t));
438 BT_ASSERT(field_path->path);
441 static inline void ctf_field_path_fini(struct ctf_field_path *field_path)
443 BT_ASSERT(field_path);
445 if (field_path->path) {
446 g_array_free(field_path->path, TRUE);
450 static inline void _ctf_named_field_class_init(struct ctf_named_field_class *named_fc)
453 named_fc->name = g_string_new(NULL);
454 BT_ASSERT(named_fc->name);
455 named_fc->orig_name = g_string_new(NULL);
456 BT_ASSERT(named_fc->orig_name);
459 static inline void _ctf_named_field_class_fini(struct ctf_named_field_class *named_fc)
463 if (named_fc->name) {
464 g_string_free(named_fc->name, TRUE);
467 if (named_fc->orig_name) {
468 g_string_free(named_fc->orig_name, TRUE);
471 ctf_field_class_destroy(named_fc->fc);
474 static inline void _ctf_field_class_enum_mapping_init(struct ctf_field_class_enum_mapping *mapping)
477 mapping->label = g_string_new(NULL);
478 BT_ASSERT(mapping->label);
479 mapping->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_range));
480 BT_ASSERT(mapping->ranges);
483 static inline void _ctf_field_class_enum_mapping_fini(struct ctf_field_class_enum_mapping *mapping)
487 if (mapping->label) {
488 g_string_free(mapping->label, TRUE);
491 if (mapping->ranges) {
492 g_array_free(mapping->ranges, TRUE);
496 static inline struct ctf_field_class_int *ctf_field_class_int_create(void)
498 struct ctf_field_class_int *fc = g_new0(struct ctf_field_class_int, 1);
501 _ctf_field_class_int_init(fc, CTF_FIELD_CLASS_TYPE_INT);
505 static inline struct ctf_field_class_float *ctf_field_class_float_create(void)
507 struct ctf_field_class_float *fc = g_new0(struct ctf_field_class_float, 1);
510 _ctf_field_class_bit_array_init(&fc->base, CTF_FIELD_CLASS_TYPE_FLOAT);
514 static inline struct ctf_field_class_string *ctf_field_class_string_create(void)
516 struct ctf_field_class_string *fc = g_new0(struct ctf_field_class_string, 1);
519 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRING, 8);
523 static inline struct ctf_field_class_enum *ctf_field_class_enum_create(void)
525 struct ctf_field_class_enum *fc = g_new0(struct ctf_field_class_enum, 1);
528 _ctf_field_class_int_init(&fc->base, CTF_FIELD_CLASS_TYPE_ENUM);
529 fc->mappings = g_array_new(FALSE, TRUE, sizeof(struct ctf_field_class_enum_mapping));
530 BT_ASSERT(fc->mappings);
534 static inline struct ctf_field_class_struct *ctf_field_class_struct_create(void)
536 struct ctf_field_class_struct *fc = g_new0(struct ctf_field_class_struct, 1);
539 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_STRUCT, 1);
540 fc->members = g_array_new(FALSE, TRUE, sizeof(struct ctf_named_field_class));
541 BT_ASSERT(fc->members);
542 fc->base.is_compound = true;
546 static inline struct ctf_field_class_variant *ctf_field_class_variant_create(void)
548 struct ctf_field_class_variant *fc = g_new0(struct ctf_field_class_variant, 1);
551 _ctf_field_class_init(&fc->base, CTF_FIELD_CLASS_TYPE_VARIANT, 1);
552 fc->options = g_array_new(FALSE, TRUE, sizeof(struct ctf_named_field_class));
553 BT_ASSERT(fc->options);
554 fc->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_field_class_variant_range));
555 BT_ASSERT(fc->ranges);
556 fc->tag_ref = g_string_new(NULL);
557 BT_ASSERT(fc->tag_ref);
558 ctf_field_path_init(&fc->tag_path);
559 fc->base.is_compound = true;
563 static inline struct ctf_field_class_array *ctf_field_class_array_create(void)
565 struct ctf_field_class_array *fc = g_new0(struct ctf_field_class_array, 1);
568 _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_ARRAY, 1);
569 fc->base.base.is_compound = true;
573 static inline struct ctf_field_class_sequence *ctf_field_class_sequence_create(void)
575 struct ctf_field_class_sequence *fc = g_new0(struct ctf_field_class_sequence, 1);
578 _ctf_field_class_init(&fc->base.base, CTF_FIELD_CLASS_TYPE_SEQUENCE, 1);
579 fc->length_ref = g_string_new(NULL);
580 BT_ASSERT(fc->length_ref);
581 ctf_field_path_init(&fc->length_path);
582 fc->base.base.is_compound = true;
586 static inline void _ctf_field_class_int_destroy(struct ctf_field_class_int *fc)
592 static inline void _ctf_field_class_enum_destroy(struct ctf_field_class_enum *fc)
599 for (i = 0; i < fc->mappings->len; i++) {
600 struct ctf_field_class_enum_mapping *mapping =
601 &bt_g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, i);
603 _ctf_field_class_enum_mapping_fini(mapping);
606 g_array_free(fc->mappings, TRUE);
612 static inline void _ctf_field_class_float_destroy(struct ctf_field_class_float *fc)
618 static inline void _ctf_field_class_string_destroy(struct ctf_field_class_string *fc)
624 static inline void _ctf_field_class_struct_destroy(struct ctf_field_class_struct *fc)
631 for (i = 0; i < fc->members->len; i++) {
632 struct ctf_named_field_class *named_fc =
633 &bt_g_array_index(fc->members, struct ctf_named_field_class, i);
635 _ctf_named_field_class_fini(named_fc);
638 g_array_free(fc->members, TRUE);
644 static inline void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base *fc)
647 ctf_field_class_destroy(fc->elem_fc);
650 static inline void _ctf_field_class_array_destroy(struct ctf_field_class_array *fc)
653 _ctf_field_class_array_base_fini(&fc->base);
657 static inline void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence *fc)
660 _ctf_field_class_array_base_fini(&fc->base);
662 if (fc->length_ref) {
663 g_string_free(fc->length_ref, TRUE);
666 ctf_field_path_fini(&fc->length_path);
670 static inline void _ctf_field_class_variant_destroy(struct ctf_field_class_variant *fc)
677 for (i = 0; i < fc->options->len; i++) {
678 struct ctf_named_field_class *named_fc =
679 &bt_g_array_index(fc->options, struct ctf_named_field_class, i);
681 _ctf_named_field_class_fini(named_fc);
684 g_array_free(fc->options, TRUE);
688 g_array_free(fc->ranges, TRUE);
692 g_string_free(fc->tag_ref, TRUE);
695 ctf_field_path_fini(&fc->tag_path);
699 static inline void ctf_field_class_destroy(struct ctf_field_class *fc)
706 case CTF_FIELD_CLASS_TYPE_INT:
707 _ctf_field_class_int_destroy(ctf_field_class_as_int(fc));
709 case CTF_FIELD_CLASS_TYPE_ENUM:
710 _ctf_field_class_enum_destroy(ctf_field_class_as_enum(fc));
712 case CTF_FIELD_CLASS_TYPE_FLOAT:
713 _ctf_field_class_float_destroy(ctf_field_class_as_float(fc));
715 case CTF_FIELD_CLASS_TYPE_STRING:
716 _ctf_field_class_string_destroy(ctf_field_class_as_string(fc));
718 case CTF_FIELD_CLASS_TYPE_STRUCT:
719 _ctf_field_class_struct_destroy(ctf_field_class_as_struct(fc));
721 case CTF_FIELD_CLASS_TYPE_ARRAY:
722 _ctf_field_class_array_destroy(ctf_field_class_as_array(fc));
724 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
725 _ctf_field_class_sequence_destroy(ctf_field_class_as_sequence(fc));
727 case CTF_FIELD_CLASS_TYPE_VARIANT:
728 _ctf_field_class_variant_destroy(ctf_field_class_as_variant(fc));
735 static inline struct ctf_range *
736 ctf_field_class_enum_mapping_borrow_range_by_index(struct ctf_field_class_enum_mapping *mapping,
739 BT_ASSERT_DBG(mapping);
740 BT_ASSERT_DBG(index < mapping->ranges->len);
741 return &bt_g_array_index(mapping->ranges, struct ctf_range, index);
744 static inline struct ctf_field_class_enum_mapping *
745 ctf_field_class_enum_borrow_mapping_by_index(struct ctf_field_class_enum *fc, uint64_t index)
748 BT_ASSERT_DBG(index < fc->mappings->len);
749 return &bt_g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, index);
752 static inline struct ctf_field_class_enum_mapping *
753 ctf_field_class_enum_borrow_mapping_by_label(struct ctf_field_class_enum *fc, const char *label)
755 struct ctf_field_class_enum_mapping *ret_mapping = NULL;
759 BT_ASSERT_DBG(label);
761 for (i = 0; i < fc->mappings->len; i++) {
762 struct ctf_field_class_enum_mapping *mapping =
763 ctf_field_class_enum_borrow_mapping_by_index(fc, i);
765 if (strcmp(mapping->label->str, label) == 0) {
766 ret_mapping = mapping;
775 static inline void ctf_field_class_enum_map_range(struct ctf_field_class_enum *fc,
776 const char *label, uint64_t u_lower,
779 struct ctf_field_class_enum_mapping *mapping = NULL;
780 struct ctf_range range = {
795 for (i = 0; i < fc->mappings->len; i++) {
796 mapping = ctf_field_class_enum_borrow_mapping_by_index(fc, i);
798 if (strcmp(mapping->label->str, label) == 0) {
803 if (i == fc->mappings->len) {
808 g_array_set_size(fc->mappings, fc->mappings->len + 1);
809 mapping = ctf_field_class_enum_borrow_mapping_by_index(fc, fc->mappings->len - 1);
810 _ctf_field_class_enum_mapping_init(mapping);
811 g_string_assign(mapping->label, label);
814 g_array_append_val(mapping->ranges, range);
817 static inline struct ctf_named_field_class *
818 ctf_field_class_struct_borrow_member_by_index(struct ctf_field_class_struct *fc, uint64_t index)
821 BT_ASSERT_DBG(index < fc->members->len);
822 return &bt_g_array_index(fc->members, struct ctf_named_field_class, index);
825 static inline struct ctf_named_field_class *
826 ctf_field_class_struct_borrow_member_by_name(struct ctf_field_class_struct *fc, const char *name)
829 struct ctf_named_field_class *ret_named_fc = NULL;
834 for (i = 0; i < fc->members->len; i++) {
835 struct ctf_named_field_class *named_fc =
836 ctf_field_class_struct_borrow_member_by_index(fc, i);
838 if (strcmp(name, named_fc->name->str) == 0) {
839 ret_named_fc = named_fc;
848 static inline struct ctf_field_class *
849 ctf_field_class_struct_borrow_member_field_class_by_name(struct ctf_field_class_struct *struct_fc,
852 struct ctf_named_field_class *named_fc = NULL;
853 struct ctf_field_class *fc = NULL;
859 named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name);
870 static inline struct ctf_field_class_int *
871 ctf_field_class_struct_borrow_member_int_field_class_by_name(
872 struct ctf_field_class_struct *struct_fc, const char *name)
874 ctf_field_class *member_fc =
875 ctf_field_class_struct_borrow_member_field_class_by_name(struct_fc, name);
881 if (member_fc->type != CTF_FIELD_CLASS_TYPE_INT &&
882 member_fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
886 return ctf_field_class_as_int(member_fc);
889 static inline void _ctf_named_field_class_unescape_orig_name(struct ctf_named_field_class *named_fc)
891 const char *name = named_fc->orig_name->str;
893 if (name[0] == '_') {
897 g_string_assign(named_fc->name, name);
900 static inline void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc,
901 const char *orig_name,
902 struct ctf_field_class *member_fc)
904 struct ctf_named_field_class *named_fc;
907 BT_ASSERT(orig_name);
908 g_array_set_size(fc->members, fc->members->len + 1);
910 named_fc = &bt_g_array_index(fc->members, struct ctf_named_field_class, fc->members->len - 1);
911 _ctf_named_field_class_init(named_fc);
912 g_string_assign(named_fc->orig_name, orig_name);
913 _ctf_named_field_class_unescape_orig_name(named_fc);
914 named_fc->fc = member_fc;
916 if (member_fc->alignment > fc->base.alignment) {
917 fc->base.alignment = member_fc->alignment;
921 static inline struct ctf_named_field_class *
922 ctf_field_class_variant_borrow_option_by_index(struct ctf_field_class_variant *fc, uint64_t index)
925 BT_ASSERT_DBG(index < fc->options->len);
926 return &bt_g_array_index(fc->options, struct ctf_named_field_class, index);
929 static inline struct ctf_named_field_class *
930 ctf_field_class_variant_borrow_option_by_name(struct ctf_field_class_variant *fc, const char *name)
933 struct ctf_named_field_class *ret_named_fc = NULL;
938 for (i = 0; i < fc->options->len; i++) {
939 struct ctf_named_field_class *named_fc =
940 ctf_field_class_variant_borrow_option_by_index(fc, i);
942 if (strcmp(name, named_fc->name->str) == 0) {
943 ret_named_fc = named_fc;
952 static inline struct ctf_field_class_variant_range *
953 ctf_field_class_variant_borrow_range_by_index(struct ctf_field_class_variant *fc, uint64_t index)
956 BT_ASSERT_DBG(index < fc->ranges->len);
957 return &bt_g_array_index(fc->ranges, struct ctf_field_class_variant_range, index);
960 static inline void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc,
961 const char *orig_name,
962 struct ctf_field_class *option_fc)
964 struct ctf_named_field_class *named_fc;
967 BT_ASSERT(orig_name);
968 g_array_set_size(fc->options, fc->options->len + 1);
970 named_fc = &bt_g_array_index(fc->options, struct ctf_named_field_class, fc->options->len - 1);
971 _ctf_named_field_class_init(named_fc);
972 g_string_assign(named_fc->orig_name, orig_name);
973 _ctf_named_field_class_unescape_orig_name(named_fc);
974 named_fc->fc = option_fc;
977 static inline void ctf_field_class_variant_set_tag_field_class(struct ctf_field_class_variant *fc,
978 struct ctf_field_class_enum *tag_fc)
986 for (option_i = 0; option_i < fc->options->len; option_i++) {
988 struct ctf_named_field_class *named_fc =
989 ctf_field_class_variant_borrow_option_by_index(fc, option_i);
990 struct ctf_field_class_enum_mapping *mapping;
992 mapping = ctf_field_class_enum_borrow_mapping_by_label(tag_fc, named_fc->orig_name->str);
997 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
998 struct ctf_range *range =
999 ctf_field_class_enum_mapping_borrow_range_by_index(mapping, range_i);
1000 struct ctf_field_class_variant_range var_range;
1002 var_range.range = *range;
1003 var_range.option_index = option_i;
1004 g_array_append_val(fc->ranges, var_range);
1009 static inline struct ctf_field_class *
1010 ctf_field_class_compound_borrow_field_class_by_index(struct ctf_field_class *comp_fc,
1013 struct ctf_field_class *fc = NULL;
1015 switch (comp_fc->type) {
1016 case CTF_FIELD_CLASS_TYPE_STRUCT:
1018 struct ctf_named_field_class *named_fc = ctf_field_class_struct_borrow_member_by_index(
1019 (struct ctf_field_class_struct *) comp_fc, index);
1021 BT_ASSERT_DBG(named_fc);
1025 case CTF_FIELD_CLASS_TYPE_VARIANT:
1027 struct ctf_named_field_class *named_fc = ctf_field_class_variant_borrow_option_by_index(
1028 (struct ctf_field_class_variant *) comp_fc, index);
1030 BT_ASSERT_DBG(named_fc);
1034 case CTF_FIELD_CLASS_TYPE_ARRAY:
1035 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1037 struct ctf_field_class_array_base *array_fc = (struct ctf_field_class_array_base *) comp_fc;
1039 fc = array_fc->elem_fc;
1049 static inline uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class *fc)
1051 uint64_t field_count;
1054 case CTF_FIELD_CLASS_TYPE_STRUCT:
1056 struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc;
1058 field_count = struct_fc->members->len;
1061 case CTF_FIELD_CLASS_TYPE_VARIANT:
1063 struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc;
1065 field_count = var_fc->options->len;
1068 case CTF_FIELD_CLASS_TYPE_ARRAY:
1069 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1071 * Array and sequence types always contain a single
1072 * member (the element type).
1083 static inline int64_t
1084 ctf_field_class_compound_get_field_class_index_from_orig_name(struct ctf_field_class *fc,
1085 const char *orig_name)
1087 int64_t ret_index = -1;
1091 case CTF_FIELD_CLASS_TYPE_STRUCT:
1093 struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc;
1095 for (i = 0; i < struct_fc->members->len; i++) {
1096 struct ctf_named_field_class *named_fc =
1097 ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
1099 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1100 ret_index = (int64_t) i;
1107 case CTF_FIELD_CLASS_TYPE_VARIANT:
1109 struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc;
1111 for (i = 0; i < var_fc->options->len; i++) {
1112 struct ctf_named_field_class *named_fc =
1113 ctf_field_class_variant_borrow_option_by_index(var_fc, i);
1115 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1116 ret_index = (int64_t) i;
1131 static inline void ctf_field_path_append_index(struct ctf_field_path *fp, int64_t index)
1134 g_array_append_val(fp->path, index);
1137 static inline int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path *fp,
1141 BT_ASSERT_DBG(index < fp->path->len);
1142 return bt_g_array_index(fp->path, int64_t, index);
1145 static inline void ctf_field_path_clear(struct ctf_field_path *fp)
1148 g_array_set_size(fp->path, 0);
1151 static inline const char *ctf_scope_string(enum ctf_scope scope)
1154 case CTF_SCOPE_PACKET_HEADER:
1155 return "PACKET_HEADER";
1156 case CTF_SCOPE_PACKET_CONTEXT:
1157 return "PACKET_CONTEXT";
1158 case CTF_SCOPE_EVENT_HEADER:
1159 return "EVENT_HEADER";
1160 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1161 return "EVENT_COMMON_CONTEXT";
1162 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1163 return "EVENT_SPECIFIC_CONTEXT";
1164 case CTF_SCOPE_EVENT_PAYLOAD:
1165 return "EVENT_PAYLOAD";
1171 static inline GString *ctf_field_path_string(struct ctf_field_path *path)
1173 GString *str = g_string_new(NULL);
1182 g_string_append_printf(str, "[%s", ctf_scope_string(path->root));
1184 for (i = 0; i < path->path->len; i++) {
1185 g_string_append_printf(str, ", %" PRId64, ctf_field_path_borrow_index_by_index(path, i));
1188 g_string_append(str, "]");
1194 static inline struct ctf_field_class *
1195 ctf_field_path_borrow_field_class(struct ctf_field_path *field_path, struct ctf_trace_class *tc,
1196 struct ctf_stream_class *sc, struct ctf_event_class *ec)
1199 struct ctf_field_class *fc;
1201 switch (field_path->root) {
1202 case CTF_SCOPE_PACKET_HEADER:
1203 fc = tc->packet_header_fc;
1205 case CTF_SCOPE_PACKET_CONTEXT:
1206 fc = sc->packet_context_fc;
1208 case CTF_SCOPE_EVENT_HEADER:
1209 fc = sc->event_header_fc;
1211 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1212 fc = sc->event_common_context_fc;
1214 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1215 fc = ec->spec_context_fc;
1217 case CTF_SCOPE_EVENT_PAYLOAD:
1218 fc = ec->payload_fc;
1226 for (i = 0; i < field_path->path->len; i++) {
1227 int64_t child_index = ctf_field_path_borrow_index_by_index(field_path, i);
1228 struct ctf_field_class *child_fc =
1229 ctf_field_class_compound_borrow_field_class_by_index(fc, child_index);
1230 BT_ASSERT_DBG(child_fc);
1238 static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc);
1240 static inline void ctf_field_class_bit_array_copy_content(struct ctf_field_class_bit_array *dst_fc,
1241 struct ctf_field_class_bit_array *src_fc)
1245 dst_fc->byte_order = src_fc->byte_order;
1246 dst_fc->size = src_fc->size;
1249 static inline void ctf_field_class_int_copy_content(struct ctf_field_class_int *dst_fc,
1250 struct ctf_field_class_int *src_fc)
1252 ctf_field_class_bit_array_copy_content(&dst_fc->base, &src_fc->base);
1253 dst_fc->meaning = src_fc->meaning;
1254 dst_fc->is_signed = src_fc->is_signed;
1255 dst_fc->disp_base = src_fc->disp_base;
1256 dst_fc->encoding = src_fc->encoding;
1257 dst_fc->mapped_clock_class = src_fc->mapped_clock_class;
1258 dst_fc->storing_index = src_fc->storing_index;
1261 static inline struct ctf_field_class_int *_ctf_field_class_int_copy(struct ctf_field_class_int *fc)
1263 struct ctf_field_class_int *copy_fc = ctf_field_class_int_create();
1266 ctf_field_class_int_copy_content(copy_fc, fc);
1270 static inline struct ctf_field_class_enum *
1271 _ctf_field_class_enum_copy(struct ctf_field_class_enum *fc)
1273 struct ctf_field_class_enum *copy_fc = ctf_field_class_enum_create();
1277 ctf_field_class_int_copy_content(©_fc->base, &fc->base);
1279 for (i = 0; i < fc->mappings->len; i++) {
1282 struct ctf_field_class_enum_mapping *mapping =
1283 &bt_g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, i);
1285 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
1286 struct ctf_range *range = &bt_g_array_index(mapping->ranges, struct ctf_range, range_i);
1288 ctf_field_class_enum_map_range(copy_fc, mapping->label->str, range->lower.u,
1296 static inline struct ctf_field_class_float *
1297 _ctf_field_class_float_copy(struct ctf_field_class_float *fc)
1299 struct ctf_field_class_float *copy_fc = ctf_field_class_float_create();
1302 ctf_field_class_bit_array_copy_content(©_fc->base, &fc->base);
1306 static inline struct ctf_field_class_string *
1307 _ctf_field_class_string_copy(struct ctf_field_class_string *)
1309 struct ctf_field_class_string *copy_fc = ctf_field_class_string_create();
1315 static inline struct ctf_field_class_struct *
1316 _ctf_field_class_struct_copy(struct ctf_field_class_struct *fc)
1318 struct ctf_field_class_struct *copy_fc = ctf_field_class_struct_create();
1323 for (i = 0; i < fc->members->len; i++) {
1324 struct ctf_named_field_class *named_fc =
1325 &bt_g_array_index(fc->members, struct ctf_named_field_class, i);
1327 ctf_field_class_struct_append_member(copy_fc, named_fc->name->str,
1328 ctf_field_class_copy(named_fc->fc));
1334 static inline void ctf_field_path_copy_content(struct ctf_field_path *dst_fp,
1335 struct ctf_field_path *src_fp)
1341 dst_fp->root = src_fp->root;
1342 ctf_field_path_clear(dst_fp);
1344 for (i = 0; i < src_fp->path->len; i++) {
1345 int64_t index = ctf_field_path_borrow_index_by_index(src_fp, i);
1347 ctf_field_path_append_index(dst_fp, index);
1351 static inline struct ctf_field_class_variant *
1352 _ctf_field_class_variant_copy(struct ctf_field_class_variant *fc)
1354 struct ctf_field_class_variant *copy_fc = ctf_field_class_variant_create();
1359 for (i = 0; i < fc->options->len; i++) {
1360 struct ctf_named_field_class *named_fc =
1361 &bt_g_array_index(fc->options, struct ctf_named_field_class, i);
1363 ctf_field_class_variant_append_option(copy_fc, named_fc->name->str,
1364 ctf_field_class_copy(named_fc->fc));
1367 for (i = 0; i < fc->ranges->len; i++) {
1368 struct ctf_field_class_variant_range *range =
1369 &bt_g_array_index(fc->ranges, struct ctf_field_class_variant_range, i);
1371 g_array_append_val(copy_fc->ranges, *range);
1374 ctf_field_path_copy_content(©_fc->tag_path, &fc->tag_path);
1375 g_string_assign(copy_fc->tag_ref, fc->tag_ref->str);
1376 copy_fc->stored_tag_index = fc->stored_tag_index;
1381 ctf_field_class_array_base_copy_content(struct ctf_field_class_array_base *dst_fc,
1382 struct ctf_field_class_array_base *src_fc)
1386 dst_fc->elem_fc = ctf_field_class_copy(src_fc->elem_fc);
1387 dst_fc->is_text = src_fc->is_text;
1390 static inline struct ctf_field_class_array *
1391 _ctf_field_class_array_copy(struct ctf_field_class_array *fc)
1393 struct ctf_field_class_array *copy_fc = ctf_field_class_array_create();
1396 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1397 copy_fc->length = fc->length;
1401 static inline struct ctf_field_class_sequence *
1402 _ctf_field_class_sequence_copy(struct ctf_field_class_sequence *fc)
1404 struct ctf_field_class_sequence *copy_fc = ctf_field_class_sequence_create();
1407 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1408 ctf_field_path_copy_content(©_fc->length_path, &fc->length_path);
1409 g_string_assign(copy_fc->length_ref, fc->length_ref->str);
1410 copy_fc->stored_length_index = fc->stored_length_index;
1414 static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc)
1416 struct ctf_field_class *copy_fc = NULL;
1423 * Translation should not have happened yet.
1425 BT_ASSERT(!fc->ir_fc);
1428 case CTF_FIELD_CLASS_TYPE_INT:
1429 copy_fc = &_ctf_field_class_int_copy(ctf_field_class_as_int(fc))->base.base;
1431 case CTF_FIELD_CLASS_TYPE_ENUM:
1432 copy_fc = &_ctf_field_class_enum_copy(ctf_field_class_as_enum(fc))->base.base.base;
1434 case CTF_FIELD_CLASS_TYPE_FLOAT:
1435 copy_fc = &_ctf_field_class_float_copy(ctf_field_class_as_float(fc))->base.base;
1437 case CTF_FIELD_CLASS_TYPE_STRING:
1438 copy_fc = &_ctf_field_class_string_copy(ctf_field_class_as_string(fc))->base;
1440 case CTF_FIELD_CLASS_TYPE_STRUCT:
1441 copy_fc = &_ctf_field_class_struct_copy(ctf_field_class_as_struct(fc))->base;
1443 case CTF_FIELD_CLASS_TYPE_ARRAY:
1444 copy_fc = &_ctf_field_class_array_copy(ctf_field_class_as_array(fc))->base.base;
1446 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1447 copy_fc = &_ctf_field_class_sequence_copy(ctf_field_class_as_sequence(fc))->base.base;
1449 case CTF_FIELD_CLASS_TYPE_VARIANT:
1450 copy_fc = &_ctf_field_class_variant_copy(ctf_field_class_as_variant(fc))->base;
1456 copy_fc->type = fc->type;
1457 copy_fc->alignment = fc->alignment;
1458 copy_fc->in_ir = fc->in_ir;
1464 static inline struct ctf_event_class *ctf_event_class_create(void)
1466 struct ctf_event_class *ec = g_new0(struct ctf_event_class, 1);
1469 ec->name = g_string_new(NULL);
1470 BT_ASSERT(ec->name);
1471 ec->emf_uri = g_string_new(NULL);
1472 BT_ASSERT(ec->emf_uri);
1473 ec->is_log_level_set = false;
1477 static inline void ctf_event_class_set_log_level(struct ctf_event_class *ec,
1478 enum bt_event_class_log_level log_level)
1481 ec->log_level = log_level;
1482 ec->is_log_level_set = true;
1485 static inline void ctf_event_class_destroy(struct ctf_event_class *ec)
1492 g_string_free(ec->name, TRUE);
1496 g_string_free(ec->emf_uri, TRUE);
1499 ctf_field_class_destroy(ec->spec_context_fc);
1500 ctf_field_class_destroy(ec->payload_fc);
1504 static inline struct ctf_stream_class *ctf_stream_class_create(void)
1506 struct ctf_stream_class *sc = g_new0(struct ctf_stream_class, 1);
1509 sc->event_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_event_class_destroy);
1510 BT_ASSERT(sc->event_classes);
1511 sc->event_classes_by_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1512 BT_ASSERT(sc->event_classes_by_id);
1516 static inline void ctf_stream_class_destroy(struct ctf_stream_class *sc)
1522 if (sc->event_classes) {
1523 g_ptr_array_free(sc->event_classes, TRUE);
1526 if (sc->event_classes_by_id) {
1527 g_hash_table_destroy(sc->event_classes_by_id);
1530 ctf_field_class_destroy(sc->packet_context_fc);
1531 ctf_field_class_destroy(sc->event_header_fc);
1532 ctf_field_class_destroy(sc->event_common_context_fc);
1536 static inline void ctf_stream_class_append_event_class(struct ctf_stream_class *sc,
1537 struct ctf_event_class *ec)
1539 g_ptr_array_add(sc->event_classes, ec);
1540 g_hash_table_insert(sc->event_classes_by_id, GUINT_TO_POINTER((guint) ec->id), ec);
1543 static inline struct ctf_event_class *
1544 ctf_stream_class_borrow_event_class_by_id(struct ctf_stream_class *sc, uint64_t type)
1547 return (struct ctf_event_class *) g_hash_table_lookup(sc->event_classes_by_id,
1548 GUINT_TO_POINTER((guint) type));
1551 static inline void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry *entry)
1554 entry->name = g_string_new(NULL);
1555 BT_ASSERT(entry->name);
1556 entry->value.str = g_string_new(NULL);
1557 BT_ASSERT(entry->value.str);
1560 static inline void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry *entry)
1565 g_string_free(entry->name, TRUE);
1568 if (entry->value.str) {
1569 g_string_free(entry->value.str, TRUE);
1573 static inline struct ctf_clock_class *ctf_clock_class_create(void)
1575 struct ctf_clock_class *cc = g_new0(struct ctf_clock_class, 1);
1578 cc->name = g_string_new(NULL);
1579 BT_ASSERT(cc->name);
1580 cc->description = g_string_new(NULL);
1581 BT_ASSERT(cc->description);
1585 static inline void ctf_clock_class_destroy(struct ctf_clock_class *cc)
1592 g_string_free(cc->name, TRUE);
1595 if (cc->description) {
1596 g_string_free(cc->description, TRUE);
1599 bt_clock_class_put_ref(cc->ir_cc);
1603 static inline struct ctf_trace_class *ctf_trace_class_create(void)
1605 struct ctf_trace_class *tc = g_new0(struct ctf_trace_class, 1);
1608 tc->default_byte_order = CTF_BYTE_ORDER_UNKNOWN;
1609 tc->clock_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_clock_class_destroy);
1610 BT_ASSERT(tc->clock_classes);
1611 tc->stream_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_stream_class_destroy);
1612 BT_ASSERT(tc->stream_classes);
1613 tc->env_entries = g_array_new(FALSE, TRUE, sizeof(struct ctf_trace_class_env_entry));
1617 static inline void ctf_trace_class_destroy(struct ctf_trace_class *tc)
1623 ctf_field_class_destroy(tc->packet_header_fc);
1625 if (tc->clock_classes) {
1626 g_ptr_array_free(tc->clock_classes, TRUE);
1629 if (tc->stream_classes) {
1630 g_ptr_array_free(tc->stream_classes, TRUE);
1633 if (tc->env_entries) {
1636 for (i = 0; i < tc->env_entries->len; i++) {
1637 struct ctf_trace_class_env_entry *entry =
1638 &bt_g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, i);
1640 _ctf_trace_class_env_entry_fini(entry);
1643 g_array_free(tc->env_entries, TRUE);
1649 static inline void ctf_trace_class_append_env_entry(struct ctf_trace_class *tc, const char *name,
1650 enum ctf_trace_class_env_entry_type type,
1651 const char *str_value, int64_t i_value)
1653 struct ctf_trace_class_env_entry *entry;
1657 g_array_set_size(tc->env_entries, tc->env_entries->len + 1);
1659 entry = &bt_g_array_index(tc->env_entries, struct ctf_trace_class_env_entry,
1660 tc->env_entries->len - 1);
1662 _ctf_trace_class_env_entry_init(entry);
1663 g_string_assign(entry->name, name);
1666 g_string_assign(entry->value.str, str_value);
1669 entry->value.i = i_value;
1672 static inline struct ctf_stream_class *
1673 ctf_trace_class_borrow_stream_class_by_id(struct ctf_trace_class *tc, uint64_t id)
1676 struct ctf_stream_class *ret_sc = NULL;
1680 for (i = 0; i < tc->stream_classes->len; i++) {
1681 struct ctf_stream_class *sc = (struct ctf_stream_class *) tc->stream_classes->pdata[i];
1693 static inline struct ctf_clock_class *
1694 ctf_trace_class_borrow_clock_class_by_name(struct ctf_trace_class *tc, const char *name)
1697 struct ctf_clock_class *ret_cc = NULL;
1700 BT_ASSERT_DBG(name);
1702 for (i = 0; i < tc->clock_classes->len; i++) {
1703 struct ctf_clock_class *cc = (struct ctf_clock_class *) tc->clock_classes->pdata[i];
1705 BT_ASSERT_DBG(cc->name);
1706 if (strcmp(cc->name->str, name) == 0) {
1716 static inline struct ctf_trace_class_env_entry *
1717 ctf_trace_class_borrow_env_entry_by_index(struct ctf_trace_class *tc, uint64_t index)
1720 BT_ASSERT_DBG(index < tc->env_entries->len);
1721 return &bt_g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, index);
1724 static inline struct ctf_trace_class_env_entry *
1725 ctf_trace_class_borrow_env_entry_by_name(struct ctf_trace_class *tc, const char *name)
1727 struct ctf_trace_class_env_entry *ret_entry = NULL;
1731 BT_ASSERT_DBG(name);
1733 for (i = 0; i < tc->env_entries->len; i++) {
1734 struct ctf_trace_class_env_entry *env_entry =
1735 ctf_trace_class_borrow_env_entry_by_index(tc, i);
1737 if (strcmp(env_entry->name->str, name) == 0) {
1738 ret_entry = env_entry;
1747 #endif /* _CTF_META_H */