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 &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 &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 &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 &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 &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 &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 struct ctf_field_class_int *int_fc = NULL;
876 int_fc = ctf_field_class_as_int(
877 ctf_field_class_struct_borrow_member_field_class_by_name(struct_fc, name));
882 if (int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_INT &&
883 int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_ENUM) {
892 static inline void _ctf_named_field_class_unescape_orig_name(struct ctf_named_field_class *named_fc)
894 const char *name = named_fc->orig_name->str;
896 if (name[0] == '_') {
900 g_string_assign(named_fc->name, name);
903 static inline void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc,
904 const char *orig_name,
905 struct ctf_field_class *member_fc)
907 struct ctf_named_field_class *named_fc;
910 BT_ASSERT(orig_name);
911 g_array_set_size(fc->members, fc->members->len + 1);
913 named_fc = &g_array_index(fc->members, struct ctf_named_field_class, fc->members->len - 1);
914 _ctf_named_field_class_init(named_fc);
915 g_string_assign(named_fc->orig_name, orig_name);
916 _ctf_named_field_class_unescape_orig_name(named_fc);
917 named_fc->fc = member_fc;
919 if (member_fc->alignment > fc->base.alignment) {
920 fc->base.alignment = member_fc->alignment;
924 static inline struct ctf_named_field_class *
925 ctf_field_class_variant_borrow_option_by_index(struct ctf_field_class_variant *fc, uint64_t index)
928 BT_ASSERT_DBG(index < fc->options->len);
929 return &g_array_index(fc->options, struct ctf_named_field_class, index);
932 static inline struct ctf_named_field_class *
933 ctf_field_class_variant_borrow_option_by_name(struct ctf_field_class_variant *fc, const char *name)
936 struct ctf_named_field_class *ret_named_fc = NULL;
941 for (i = 0; i < fc->options->len; i++) {
942 struct ctf_named_field_class *named_fc =
943 ctf_field_class_variant_borrow_option_by_index(fc, i);
945 if (strcmp(name, named_fc->name->str) == 0) {
946 ret_named_fc = named_fc;
955 static inline struct ctf_field_class_variant_range *
956 ctf_field_class_variant_borrow_range_by_index(struct ctf_field_class_variant *fc, uint64_t index)
959 BT_ASSERT_DBG(index < fc->ranges->len);
960 return &g_array_index(fc->ranges, struct ctf_field_class_variant_range, index);
963 static inline void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc,
964 const char *orig_name,
965 struct ctf_field_class *option_fc)
967 struct ctf_named_field_class *named_fc;
970 BT_ASSERT(orig_name);
971 g_array_set_size(fc->options, fc->options->len + 1);
973 named_fc = &g_array_index(fc->options, struct ctf_named_field_class, fc->options->len - 1);
974 _ctf_named_field_class_init(named_fc);
975 g_string_assign(named_fc->orig_name, orig_name);
976 _ctf_named_field_class_unescape_orig_name(named_fc);
977 named_fc->fc = option_fc;
980 static inline void ctf_field_class_variant_set_tag_field_class(struct ctf_field_class_variant *fc,
981 struct ctf_field_class_enum *tag_fc)
989 for (option_i = 0; option_i < fc->options->len; option_i++) {
991 struct ctf_named_field_class *named_fc =
992 ctf_field_class_variant_borrow_option_by_index(fc, option_i);
993 struct ctf_field_class_enum_mapping *mapping;
995 mapping = ctf_field_class_enum_borrow_mapping_by_label(tag_fc, named_fc->orig_name->str);
1000 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
1001 struct ctf_range *range =
1002 ctf_field_class_enum_mapping_borrow_range_by_index(mapping, range_i);
1003 struct ctf_field_class_variant_range var_range;
1005 var_range.range = *range;
1006 var_range.option_index = option_i;
1007 g_array_append_val(fc->ranges, var_range);
1012 static inline struct ctf_field_class *
1013 ctf_field_class_compound_borrow_field_class_by_index(struct ctf_field_class *comp_fc,
1016 struct ctf_field_class *fc = NULL;
1018 switch (comp_fc->type) {
1019 case CTF_FIELD_CLASS_TYPE_STRUCT:
1021 struct ctf_named_field_class *named_fc = ctf_field_class_struct_borrow_member_by_index(
1022 (struct ctf_field_class_struct *) comp_fc, index);
1024 BT_ASSERT_DBG(named_fc);
1028 case CTF_FIELD_CLASS_TYPE_VARIANT:
1030 struct ctf_named_field_class *named_fc = ctf_field_class_variant_borrow_option_by_index(
1031 (struct ctf_field_class_variant *) comp_fc, index);
1033 BT_ASSERT_DBG(named_fc);
1037 case CTF_FIELD_CLASS_TYPE_ARRAY:
1038 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1040 struct ctf_field_class_array_base *array_fc = (struct ctf_field_class_array_base *) comp_fc;
1042 fc = array_fc->elem_fc;
1052 static inline uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class *fc)
1054 uint64_t field_count;
1057 case CTF_FIELD_CLASS_TYPE_STRUCT:
1059 struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc;
1061 field_count = struct_fc->members->len;
1064 case CTF_FIELD_CLASS_TYPE_VARIANT:
1066 struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc;
1068 field_count = var_fc->options->len;
1071 case CTF_FIELD_CLASS_TYPE_ARRAY:
1072 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1074 * Array and sequence types always contain a single
1075 * member (the element type).
1086 static inline int64_t
1087 ctf_field_class_compound_get_field_class_index_from_orig_name(struct ctf_field_class *fc,
1088 const char *orig_name)
1090 int64_t ret_index = -1;
1094 case CTF_FIELD_CLASS_TYPE_STRUCT:
1096 struct ctf_field_class_struct *struct_fc = (struct ctf_field_class_struct *) fc;
1098 for (i = 0; i < struct_fc->members->len; i++) {
1099 struct ctf_named_field_class *named_fc =
1100 ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
1102 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1103 ret_index = (int64_t) i;
1110 case CTF_FIELD_CLASS_TYPE_VARIANT:
1112 struct ctf_field_class_variant *var_fc = (struct ctf_field_class_variant *) fc;
1114 for (i = 0; i < var_fc->options->len; i++) {
1115 struct ctf_named_field_class *named_fc =
1116 ctf_field_class_variant_borrow_option_by_index(var_fc, i);
1118 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1119 ret_index = (int64_t) i;
1134 static inline void ctf_field_path_append_index(struct ctf_field_path *fp, int64_t index)
1137 g_array_append_val(fp->path, index);
1140 static inline int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path *fp,
1144 BT_ASSERT_DBG(index < fp->path->len);
1145 return g_array_index(fp->path, int64_t, index);
1148 static inline void ctf_field_path_clear(struct ctf_field_path *fp)
1151 g_array_set_size(fp->path, 0);
1154 static inline const char *ctf_scope_string(enum ctf_scope scope)
1157 case CTF_SCOPE_PACKET_HEADER:
1158 return "PACKET_HEADER";
1159 case CTF_SCOPE_PACKET_CONTEXT:
1160 return "PACKET_CONTEXT";
1161 case CTF_SCOPE_EVENT_HEADER:
1162 return "EVENT_HEADER";
1163 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1164 return "EVENT_COMMON_CONTEXT";
1165 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1166 return "EVENT_SPECIFIC_CONTEXT";
1167 case CTF_SCOPE_EVENT_PAYLOAD:
1168 return "EVENT_PAYLOAD";
1174 static inline GString *ctf_field_path_string(struct ctf_field_path *path)
1176 GString *str = g_string_new(NULL);
1185 g_string_append_printf(str, "[%s", ctf_scope_string(path->root));
1187 for (i = 0; i < path->path->len; i++) {
1188 g_string_append_printf(str, ", %" PRId64, ctf_field_path_borrow_index_by_index(path, i));
1191 g_string_append(str, "]");
1197 static inline struct ctf_field_class *
1198 ctf_field_path_borrow_field_class(struct ctf_field_path *field_path, struct ctf_trace_class *tc,
1199 struct ctf_stream_class *sc, struct ctf_event_class *ec)
1202 struct ctf_field_class *fc;
1204 switch (field_path->root) {
1205 case CTF_SCOPE_PACKET_HEADER:
1206 fc = tc->packet_header_fc;
1208 case CTF_SCOPE_PACKET_CONTEXT:
1209 fc = sc->packet_context_fc;
1211 case CTF_SCOPE_EVENT_HEADER:
1212 fc = sc->event_header_fc;
1214 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1215 fc = sc->event_common_context_fc;
1217 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1218 fc = ec->spec_context_fc;
1220 case CTF_SCOPE_EVENT_PAYLOAD:
1221 fc = ec->payload_fc;
1229 for (i = 0; i < field_path->path->len; i++) {
1230 int64_t child_index = ctf_field_path_borrow_index_by_index(field_path, i);
1231 struct ctf_field_class *child_fc =
1232 ctf_field_class_compound_borrow_field_class_by_index(fc, child_index);
1233 BT_ASSERT_DBG(child_fc);
1241 static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc);
1243 static inline void ctf_field_class_bit_array_copy_content(struct ctf_field_class_bit_array *dst_fc,
1244 struct ctf_field_class_bit_array *src_fc)
1248 dst_fc->byte_order = src_fc->byte_order;
1249 dst_fc->size = src_fc->size;
1252 static inline void ctf_field_class_int_copy_content(struct ctf_field_class_int *dst_fc,
1253 struct ctf_field_class_int *src_fc)
1255 ctf_field_class_bit_array_copy_content(&dst_fc->base, &src_fc->base);
1256 dst_fc->meaning = src_fc->meaning;
1257 dst_fc->is_signed = src_fc->is_signed;
1258 dst_fc->disp_base = src_fc->disp_base;
1259 dst_fc->encoding = src_fc->encoding;
1260 dst_fc->mapped_clock_class = src_fc->mapped_clock_class;
1261 dst_fc->storing_index = src_fc->storing_index;
1264 static inline struct ctf_field_class_int *_ctf_field_class_int_copy(struct ctf_field_class_int *fc)
1266 struct ctf_field_class_int *copy_fc = ctf_field_class_int_create();
1269 ctf_field_class_int_copy_content(copy_fc, fc);
1273 static inline struct ctf_field_class_enum *
1274 _ctf_field_class_enum_copy(struct ctf_field_class_enum *fc)
1276 struct ctf_field_class_enum *copy_fc = ctf_field_class_enum_create();
1280 ctf_field_class_int_copy_content(©_fc->base, &fc->base);
1282 for (i = 0; i < fc->mappings->len; i++) {
1285 struct ctf_field_class_enum_mapping *mapping =
1286 &g_array_index(fc->mappings, struct ctf_field_class_enum_mapping, i);
1288 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
1289 struct ctf_range *range = &g_array_index(mapping->ranges, struct ctf_range, range_i);
1291 ctf_field_class_enum_map_range(copy_fc, mapping->label->str, range->lower.u,
1299 static inline struct ctf_field_class_float *
1300 _ctf_field_class_float_copy(struct ctf_field_class_float *fc)
1302 struct ctf_field_class_float *copy_fc = ctf_field_class_float_create();
1305 ctf_field_class_bit_array_copy_content(©_fc->base, &fc->base);
1309 static inline struct ctf_field_class_string *
1310 _ctf_field_class_string_copy(struct ctf_field_class_string *fc)
1312 struct ctf_field_class_string *copy_fc = ctf_field_class_string_create();
1318 static inline struct ctf_field_class_struct *
1319 _ctf_field_class_struct_copy(struct ctf_field_class_struct *fc)
1321 struct ctf_field_class_struct *copy_fc = ctf_field_class_struct_create();
1326 for (i = 0; i < fc->members->len; i++) {
1327 struct ctf_named_field_class *named_fc =
1328 &g_array_index(fc->members, struct ctf_named_field_class, i);
1330 ctf_field_class_struct_append_member(copy_fc, named_fc->name->str,
1331 ctf_field_class_copy(named_fc->fc));
1337 static inline void ctf_field_path_copy_content(struct ctf_field_path *dst_fp,
1338 struct ctf_field_path *src_fp)
1344 dst_fp->root = src_fp->root;
1345 ctf_field_path_clear(dst_fp);
1347 for (i = 0; i < src_fp->path->len; i++) {
1348 int64_t index = ctf_field_path_borrow_index_by_index(src_fp, i);
1350 ctf_field_path_append_index(dst_fp, index);
1354 static inline struct ctf_field_class_variant *
1355 _ctf_field_class_variant_copy(struct ctf_field_class_variant *fc)
1357 struct ctf_field_class_variant *copy_fc = ctf_field_class_variant_create();
1362 for (i = 0; i < fc->options->len; i++) {
1363 struct ctf_named_field_class *named_fc =
1364 &g_array_index(fc->options, struct ctf_named_field_class, i);
1366 ctf_field_class_variant_append_option(copy_fc, named_fc->name->str,
1367 ctf_field_class_copy(named_fc->fc));
1370 for (i = 0; i < fc->ranges->len; i++) {
1371 struct ctf_field_class_variant_range *range =
1372 &g_array_index(fc->ranges, struct ctf_field_class_variant_range, i);
1374 g_array_append_val(copy_fc->ranges, *range);
1377 ctf_field_path_copy_content(©_fc->tag_path, &fc->tag_path);
1378 g_string_assign(copy_fc->tag_ref, fc->tag_ref->str);
1379 copy_fc->stored_tag_index = fc->stored_tag_index;
1384 ctf_field_class_array_base_copy_content(struct ctf_field_class_array_base *dst_fc,
1385 struct ctf_field_class_array_base *src_fc)
1389 dst_fc->elem_fc = ctf_field_class_copy(src_fc->elem_fc);
1390 dst_fc->is_text = src_fc->is_text;
1393 static inline struct ctf_field_class_array *
1394 _ctf_field_class_array_copy(struct ctf_field_class_array *fc)
1396 struct ctf_field_class_array *copy_fc = ctf_field_class_array_create();
1399 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1400 copy_fc->length = fc->length;
1404 static inline struct ctf_field_class_sequence *
1405 _ctf_field_class_sequence_copy(struct ctf_field_class_sequence *fc)
1407 struct ctf_field_class_sequence *copy_fc = ctf_field_class_sequence_create();
1410 ctf_field_class_array_base_copy_content(©_fc->base, &fc->base);
1411 ctf_field_path_copy_content(©_fc->length_path, &fc->length_path);
1412 g_string_assign(copy_fc->length_ref, fc->length_ref->str);
1413 copy_fc->stored_length_index = fc->stored_length_index;
1417 static inline struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc)
1419 struct ctf_field_class *copy_fc = NULL;
1426 * Translation should not have happened yet.
1428 BT_ASSERT(!fc->ir_fc);
1431 case CTF_FIELD_CLASS_TYPE_INT:
1432 copy_fc = &_ctf_field_class_int_copy(ctf_field_class_as_int(fc))->base.base;
1434 case CTF_FIELD_CLASS_TYPE_ENUM:
1435 copy_fc = &_ctf_field_class_enum_copy(ctf_field_class_as_enum(fc))->base.base.base;
1437 case CTF_FIELD_CLASS_TYPE_FLOAT:
1438 copy_fc = &_ctf_field_class_float_copy(ctf_field_class_as_float(fc))->base.base;
1440 case CTF_FIELD_CLASS_TYPE_STRING:
1441 copy_fc = &_ctf_field_class_string_copy(ctf_field_class_as_string(fc))->base;
1443 case CTF_FIELD_CLASS_TYPE_STRUCT:
1444 copy_fc = &_ctf_field_class_struct_copy(ctf_field_class_as_struct(fc))->base;
1446 case CTF_FIELD_CLASS_TYPE_ARRAY:
1447 copy_fc = &_ctf_field_class_array_copy(ctf_field_class_as_array(fc))->base.base;
1449 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1450 copy_fc = &_ctf_field_class_sequence_copy(ctf_field_class_as_sequence(fc))->base.base;
1452 case CTF_FIELD_CLASS_TYPE_VARIANT:
1453 copy_fc = &_ctf_field_class_variant_copy(ctf_field_class_as_variant(fc))->base;
1459 copy_fc->type = fc->type;
1460 copy_fc->alignment = fc->alignment;
1461 copy_fc->in_ir = fc->in_ir;
1467 static inline struct ctf_event_class *ctf_event_class_create(void)
1469 struct ctf_event_class *ec = g_new0(struct ctf_event_class, 1);
1472 ec->name = g_string_new(NULL);
1473 BT_ASSERT(ec->name);
1474 ec->emf_uri = g_string_new(NULL);
1475 BT_ASSERT(ec->emf_uri);
1476 ec->is_log_level_set = false;
1480 static inline void ctf_event_class_set_log_level(struct ctf_event_class *ec,
1481 enum bt_event_class_log_level log_level)
1484 ec->log_level = log_level;
1485 ec->is_log_level_set = true;
1488 static inline void ctf_event_class_destroy(struct ctf_event_class *ec)
1495 g_string_free(ec->name, TRUE);
1499 g_string_free(ec->emf_uri, TRUE);
1502 ctf_field_class_destroy(ec->spec_context_fc);
1503 ctf_field_class_destroy(ec->payload_fc);
1507 static inline struct ctf_stream_class *ctf_stream_class_create(void)
1509 struct ctf_stream_class *sc = g_new0(struct ctf_stream_class, 1);
1512 sc->event_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_event_class_destroy);
1513 BT_ASSERT(sc->event_classes);
1514 sc->event_classes_by_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1515 BT_ASSERT(sc->event_classes_by_id);
1519 static inline void ctf_stream_class_destroy(struct ctf_stream_class *sc)
1525 if (sc->event_classes) {
1526 g_ptr_array_free(sc->event_classes, TRUE);
1529 if (sc->event_classes_by_id) {
1530 g_hash_table_destroy(sc->event_classes_by_id);
1533 ctf_field_class_destroy(sc->packet_context_fc);
1534 ctf_field_class_destroy(sc->event_header_fc);
1535 ctf_field_class_destroy(sc->event_common_context_fc);
1539 static inline void ctf_stream_class_append_event_class(struct ctf_stream_class *sc,
1540 struct ctf_event_class *ec)
1542 g_ptr_array_add(sc->event_classes, ec);
1543 g_hash_table_insert(sc->event_classes_by_id, GUINT_TO_POINTER((guint) ec->id), ec);
1546 static inline struct ctf_event_class *
1547 ctf_stream_class_borrow_event_class_by_id(struct ctf_stream_class *sc, uint64_t type)
1550 return (struct ctf_event_class *) g_hash_table_lookup(sc->event_classes_by_id,
1551 GUINT_TO_POINTER((guint) type));
1554 static inline void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry *entry)
1557 entry->name = g_string_new(NULL);
1558 BT_ASSERT(entry->name);
1559 entry->value.str = g_string_new(NULL);
1560 BT_ASSERT(entry->value.str);
1563 static inline void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry *entry)
1568 g_string_free(entry->name, TRUE);
1571 if (entry->value.str) {
1572 g_string_free(entry->value.str, TRUE);
1576 static inline struct ctf_clock_class *ctf_clock_class_create(void)
1578 struct ctf_clock_class *cc = g_new0(struct ctf_clock_class, 1);
1581 cc->name = g_string_new(NULL);
1582 BT_ASSERT(cc->name);
1583 cc->description = g_string_new(NULL);
1584 BT_ASSERT(cc->description);
1588 static inline void ctf_clock_class_destroy(struct ctf_clock_class *cc)
1595 g_string_free(cc->name, TRUE);
1598 if (cc->description) {
1599 g_string_free(cc->description, TRUE);
1602 bt_clock_class_put_ref(cc->ir_cc);
1606 static inline struct ctf_trace_class *ctf_trace_class_create(void)
1608 struct ctf_trace_class *tc = g_new0(struct ctf_trace_class, 1);
1611 tc->default_byte_order = CTF_BYTE_ORDER_UNKNOWN;
1612 tc->clock_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_clock_class_destroy);
1613 BT_ASSERT(tc->clock_classes);
1614 tc->stream_classes = g_ptr_array_new_with_free_func((GDestroyNotify) ctf_stream_class_destroy);
1615 BT_ASSERT(tc->stream_classes);
1616 tc->env_entries = g_array_new(FALSE, TRUE, sizeof(struct ctf_trace_class_env_entry));
1620 static inline void ctf_trace_class_destroy(struct ctf_trace_class *tc)
1626 ctf_field_class_destroy(tc->packet_header_fc);
1628 if (tc->clock_classes) {
1629 g_ptr_array_free(tc->clock_classes, TRUE);
1632 if (tc->stream_classes) {
1633 g_ptr_array_free(tc->stream_classes, TRUE);
1636 if (tc->env_entries) {
1639 for (i = 0; i < tc->env_entries->len; i++) {
1640 struct ctf_trace_class_env_entry *entry =
1641 &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, i);
1643 _ctf_trace_class_env_entry_fini(entry);
1646 g_array_free(tc->env_entries, TRUE);
1652 static inline void ctf_trace_class_append_env_entry(struct ctf_trace_class *tc, const char *name,
1653 enum ctf_trace_class_env_entry_type type,
1654 const char *str_value, int64_t i_value)
1656 struct ctf_trace_class_env_entry *entry;
1660 g_array_set_size(tc->env_entries, tc->env_entries->len + 1);
1663 &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, tc->env_entries->len - 1);
1665 _ctf_trace_class_env_entry_init(entry);
1666 g_string_assign(entry->name, name);
1669 g_string_assign(entry->value.str, str_value);
1672 entry->value.i = i_value;
1675 static inline struct ctf_stream_class *
1676 ctf_trace_class_borrow_stream_class_by_id(struct ctf_trace_class *tc, uint64_t id)
1679 struct ctf_stream_class *ret_sc = NULL;
1683 for (i = 0; i < tc->stream_classes->len; i++) {
1684 struct ctf_stream_class *sc = (struct ctf_stream_class *) tc->stream_classes->pdata[i];
1696 static inline struct ctf_clock_class *
1697 ctf_trace_class_borrow_clock_class_by_name(struct ctf_trace_class *tc, const char *name)
1700 struct ctf_clock_class *ret_cc = NULL;
1703 BT_ASSERT_DBG(name);
1705 for (i = 0; i < tc->clock_classes->len; i++) {
1706 struct ctf_clock_class *cc = (struct ctf_clock_class *) tc->clock_classes->pdata[i];
1708 BT_ASSERT_DBG(cc->name);
1709 if (strcmp(cc->name->str, name) == 0) {
1719 static inline struct ctf_trace_class_env_entry *
1720 ctf_trace_class_borrow_env_entry_by_index(struct ctf_trace_class *tc, uint64_t index)
1723 BT_ASSERT_DBG(index < tc->env_entries->len);
1724 return &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry, index);
1727 static inline struct ctf_trace_class_env_entry *
1728 ctf_trace_class_borrow_env_entry_by_name(struct ctf_trace_class *tc, const char *name)
1730 struct ctf_trace_class_env_entry *ret_entry = NULL;
1734 BT_ASSERT_DBG(name);
1736 for (i = 0; i < tc->env_entries->len; i++) {
1737 struct ctf_trace_class_env_entry *env_entry =
1738 ctf_trace_class_borrow_env_entry_by_index(tc, i);
1740 if (strcmp(env_entry->name->str, name) == 0) {
1741 ret_entry = env_entry;
1750 #endif /* _CTF_META_H */