5 * Copyright 2018 - Philippe Proulx <pproulx@efficios.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
18 #include <babeltrace2/babeltrace.h>
19 #include "common/common.h"
20 #include "common/uuid.h"
21 #include "common/assert.h"
26 enum ctf_field_class_type
{
27 CTF_FIELD_CLASS_TYPE_INT
,
28 CTF_FIELD_CLASS_TYPE_ENUM
,
29 CTF_FIELD_CLASS_TYPE_FLOAT
,
30 CTF_FIELD_CLASS_TYPE_STRING
,
31 CTF_FIELD_CLASS_TYPE_STRUCT
,
32 CTF_FIELD_CLASS_TYPE_ARRAY
,
33 CTF_FIELD_CLASS_TYPE_SEQUENCE
,
34 CTF_FIELD_CLASS_TYPE_VARIANT
,
37 enum ctf_field_class_meaning
{
38 CTF_FIELD_CLASS_MEANING_NONE
,
39 CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME
,
40 CTF_FIELD_CLASS_MEANING_PACKET_END_TIME
,
41 CTF_FIELD_CLASS_MEANING_EVENT_CLASS_ID
,
42 CTF_FIELD_CLASS_MEANING_STREAM_CLASS_ID
,
43 CTF_FIELD_CLASS_MEANING_DATA_STREAM_ID
,
44 CTF_FIELD_CLASS_MEANING_MAGIC
,
45 CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT
,
46 CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT
,
47 CTF_FIELD_CLASS_MEANING_EXP_PACKET_TOTAL_SIZE
,
48 CTF_FIELD_CLASS_MEANING_EXP_PACKET_CONTENT_SIZE
,
49 CTF_FIELD_CLASS_MEANING_UUID
,
53 CTF_BYTE_ORDER_DEFAULT
,
54 CTF_BYTE_ORDER_LITTLE
,
64 CTF_SCOPE_PACKET_HEADER
,
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
{
77 int64_t offset_seconds
;
78 uint64_t offset_cycles
;
83 /* Weak, set during translation */
84 bt_clock_class
*ir_cc
;
87 struct ctf_field_class
{
88 enum ctf_field_class_type type
;
89 unsigned int alignment
;
93 /* Weak, set during translation. NULL if `in_ir` is false below. */
94 bt_field_class
*ir_fc
;
97 struct ctf_field_class_bit_array
{
98 struct ctf_field_class base
;
99 enum ctf_byte_order byte_order
;
103 struct ctf_field_class_int
{
104 struct ctf_field_class_bit_array base
;
105 enum ctf_field_class_meaning meaning
;
107 bt_field_class_integer_preferred_display_base disp_base
;
108 enum ctf_encoding encoding
;
109 int64_t storing_index
;
112 struct ctf_clock_class
*mapped_clock_class
;
127 struct ctf_field_class_enum_mapping
{
129 struct ctf_range range
;
132 struct ctf_field_class_enum
{
133 struct ctf_field_class_int base
;
135 /* Array of `struct ctf_field_class_enum_mapping` */
139 struct ctf_field_class_float
{
140 struct ctf_field_class_bit_array base
;
143 struct ctf_field_class_string
{
144 struct ctf_field_class base
;
145 enum ctf_encoding encoding
;
148 struct ctf_named_field_class
{
152 struct ctf_field_class
*fc
;
155 struct ctf_field_class_struct
{
156 struct ctf_field_class base
;
158 /* Array of `struct ctf_named_field_class` */
162 struct ctf_field_path
{
165 /* Array of `int64_t` */
169 struct ctf_field_class_variant_range
{
170 struct ctf_range range
;
171 uint64_t option_index
;
174 struct ctf_field_class_variant
{
175 struct ctf_field_class base
;
177 struct ctf_field_path tag_path
;
178 uint64_t stored_tag_index
;
180 /* Array of `struct ctf_named_field_class` */
183 /* Array of `struct ctf_field_class_variant_range` */
187 struct ctf_field_class_enum
*tag_fc
;
190 struct ctf_field_class_array_base
{
191 struct ctf_field_class base
;
192 struct ctf_field_class
*elem_fc
;
196 struct ctf_field_class_array
{
197 struct ctf_field_class_array_base base
;
198 enum ctf_field_class_meaning meaning
;
202 struct ctf_field_class_sequence
{
203 struct ctf_field_class_array_base base
;
205 struct ctf_field_path length_path
;
206 uint64_t stored_length_index
;
209 struct ctf_field_class_int
*length_fc
;
212 struct ctf_event_class
{
216 bt_event_class_log_level log_level
;
220 struct ctf_field_class
*spec_context_fc
;
223 struct ctf_field_class
*payload_fc
;
225 /* Weak, set during translation */
226 bt_event_class
*ir_ec
;
229 struct ctf_stream_class
{
232 bool packets_have_ts_begin
;
233 bool packets_have_ts_end
;
234 bool has_discarded_events
;
235 bool has_discarded_packets
;
236 bool discarded_events_have_default_cs
;
237 bool discarded_packets_have_default_cs
;
240 struct ctf_field_class
*packet_context_fc
;
243 struct ctf_field_class
*event_header_fc
;
246 struct ctf_field_class
*event_common_context_fc
;
248 /* Array of `struct ctf_event_class *`, owned by this */
249 GPtrArray
*event_classes
;
252 * Hash table mapping event class IDs to `struct ctf_event_class *`,
255 GHashTable
*event_classes_by_id
;
258 struct ctf_clock_class
*default_clock_class
;
260 /* Weak, set during translation */
261 bt_stream_class
*ir_sc
;
264 enum ctf_trace_class_env_entry_type
{
265 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
266 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
269 struct ctf_trace_class_env_entry
{
270 enum ctf_trace_class_env_entry_type type
;
279 struct ctf_trace_class
{
284 enum ctf_byte_order default_byte_order
;
287 struct ctf_field_class
*packet_header_fc
;
289 uint64_t stored_value_count
;
291 /* Array of `struct ctf_clock_class *` (owned by this) */
292 GPtrArray
*clock_classes
;
294 /* Array of `struct ctf_stream_class *` */
295 GPtrArray
*stream_classes
;
297 /* Array of `struct ctf_trace_class_env_entry` */
302 /* Weak, set during translation */
303 bt_trace_class
*ir_tc
;
307 void ctf_field_class_destroy(struct ctf_field_class
*fc
);
310 void _ctf_field_class_init(struct ctf_field_class
*fc
,
311 enum ctf_field_class_type type
, unsigned int alignment
)
315 fc
->alignment
= alignment
;
320 void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array
*fc
,
321 enum ctf_field_class_type type
)
323 _ctf_field_class_init((void *) fc
, type
, 1);
327 void _ctf_field_class_int_init(struct ctf_field_class_int
*fc
,
328 enum ctf_field_class_type type
)
330 _ctf_field_class_bit_array_init((void *) fc
, type
);
331 fc
->meaning
= CTF_FIELD_CLASS_MEANING_NONE
;
332 fc
->storing_index
= -1;
336 void ctf_field_path_init(struct ctf_field_path
*field_path
)
338 BT_ASSERT(field_path
);
339 field_path
->path
= g_array_new(FALSE
, TRUE
, sizeof(int64_t));
340 BT_ASSERT(field_path
->path
);
344 void ctf_field_path_fini(struct ctf_field_path
*field_path
)
346 BT_ASSERT(field_path
);
348 if (field_path
->path
) {
349 g_array_free(field_path
->path
, TRUE
);
354 void _ctf_named_field_class_init(struct ctf_named_field_class
*named_fc
)
357 named_fc
->name
= g_string_new(NULL
);
358 BT_ASSERT(named_fc
->name
);
362 void _ctf_named_field_class_fini(struct ctf_named_field_class
*named_fc
)
366 if (named_fc
->name
) {
367 g_string_free(named_fc
->name
, TRUE
);
370 ctf_field_class_destroy(named_fc
->fc
);
374 void _ctf_field_class_enum_mapping_init(
375 struct ctf_field_class_enum_mapping
*mapping
)
378 mapping
->label
= g_string_new(NULL
);
379 BT_ASSERT(mapping
->label
);
383 void _ctf_field_class_enum_mapping_fini(
384 struct ctf_field_class_enum_mapping
*mapping
)
388 if (mapping
->label
) {
389 g_string_free(mapping
->label
, TRUE
);
394 struct ctf_field_class_int
*ctf_field_class_int_create(void)
396 struct ctf_field_class_int
*fc
= g_new0(struct ctf_field_class_int
, 1);
399 _ctf_field_class_int_init(fc
, CTF_FIELD_CLASS_TYPE_INT
);
404 struct ctf_field_class_float
*ctf_field_class_float_create(void)
406 struct ctf_field_class_float
*fc
=
407 g_new0(struct ctf_field_class_float
, 1);
410 _ctf_field_class_bit_array_init((void *) fc
, CTF_FIELD_CLASS_TYPE_FLOAT
);
415 struct ctf_field_class_string
*ctf_field_class_string_create(void)
417 struct ctf_field_class_string
*fc
=
418 g_new0(struct ctf_field_class_string
, 1);
421 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_STRING
, 8);
426 struct ctf_field_class_enum
*ctf_field_class_enum_create(void)
428 struct ctf_field_class_enum
*fc
= g_new0(struct ctf_field_class_enum
, 1);
431 _ctf_field_class_int_init((void *) fc
, CTF_FIELD_CLASS_TYPE_ENUM
);
432 fc
->mappings
= g_array_new(FALSE
, TRUE
,
433 sizeof(struct ctf_field_class_enum_mapping
));
434 BT_ASSERT(fc
->mappings
);
439 struct ctf_field_class_struct
*ctf_field_class_struct_create(void)
441 struct ctf_field_class_struct
*fc
=
442 g_new0(struct ctf_field_class_struct
, 1);
445 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_STRUCT
, 1);
446 fc
->members
= g_array_new(FALSE
, TRUE
,
447 sizeof(struct ctf_named_field_class
));
448 BT_ASSERT(fc
->members
);
449 fc
->base
.is_compound
= true;
454 struct ctf_field_class_variant
*ctf_field_class_variant_create(void)
456 struct ctf_field_class_variant
*fc
=
457 g_new0(struct ctf_field_class_variant
, 1);
460 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_VARIANT
, 1);
461 fc
->options
= g_array_new(FALSE
, TRUE
,
462 sizeof(struct ctf_named_field_class
));
463 BT_ASSERT(fc
->options
);
464 fc
->ranges
= g_array_new(FALSE
, TRUE
,
465 sizeof(struct ctf_field_class_variant_range
));
466 BT_ASSERT(fc
->ranges
);
467 fc
->tag_ref
= g_string_new(NULL
);
468 BT_ASSERT(fc
->tag_ref
);
469 ctf_field_path_init(&fc
->tag_path
);
470 fc
->base
.is_compound
= true;
475 struct ctf_field_class_array
*ctf_field_class_array_create(void)
477 struct ctf_field_class_array
*fc
=
478 g_new0(struct ctf_field_class_array
, 1);
481 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_ARRAY
, 1);
482 fc
->base
.base
.is_compound
= true;
487 struct ctf_field_class_sequence
*ctf_field_class_sequence_create(void)
489 struct ctf_field_class_sequence
*fc
=
490 g_new0(struct ctf_field_class_sequence
, 1);
493 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_SEQUENCE
, 1);
494 fc
->length_ref
= g_string_new(NULL
);
495 BT_ASSERT(fc
->length_ref
);
496 ctf_field_path_init(&fc
->length_path
);
497 fc
->base
.base
.is_compound
= true;
502 void _ctf_field_class_int_destroy(struct ctf_field_class_int
*fc
)
509 void _ctf_field_class_enum_destroy(struct ctf_field_class_enum
*fc
)
516 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
517 struct ctf_field_class_enum_mapping
*mapping
=
518 &g_array_index(fc
->mappings
,
519 struct ctf_field_class_enum_mapping
, i
);
521 _ctf_field_class_enum_mapping_fini(mapping
);
524 g_array_free(fc
->mappings
, TRUE
);
531 void _ctf_field_class_float_destroy(struct ctf_field_class_float
*fc
)
538 void _ctf_field_class_string_destroy(struct ctf_field_class_string
*fc
)
545 void _ctf_field_class_struct_destroy(struct ctf_field_class_struct
*fc
)
552 for (i
= 0; i
< fc
->members
->len
; i
++) {
553 struct ctf_named_field_class
*named_fc
=
554 &g_array_index(fc
->members
,
555 struct ctf_named_field_class
, i
);
557 _ctf_named_field_class_fini(named_fc
);
560 g_array_free(fc
->members
, TRUE
);
567 void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base
*fc
)
570 ctf_field_class_destroy(fc
->elem_fc
);
574 void _ctf_field_class_array_destroy(struct ctf_field_class_array
*fc
)
577 _ctf_field_class_array_base_fini((void *) fc
);
582 void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence
*fc
)
585 _ctf_field_class_array_base_fini((void *) fc
);
587 if (fc
->length_ref
) {
588 g_string_free(fc
->length_ref
, TRUE
);
591 ctf_field_path_fini(&fc
->length_path
);
596 void _ctf_field_class_variant_destroy(struct ctf_field_class_variant
*fc
)
603 for (i
= 0; i
< fc
->options
->len
; i
++) {
604 struct ctf_named_field_class
*named_fc
=
605 &g_array_index(fc
->options
,
606 struct ctf_named_field_class
, i
);
608 _ctf_named_field_class_fini(named_fc
);
611 g_array_free(fc
->options
, TRUE
);
615 g_array_free(fc
->ranges
, TRUE
);
619 g_string_free(fc
->tag_ref
, TRUE
);
622 ctf_field_path_fini(&fc
->tag_path
);
627 void ctf_field_class_destroy(struct ctf_field_class
*fc
)
634 case CTF_FIELD_CLASS_TYPE_INT
:
635 _ctf_field_class_int_destroy((void *) fc
);
637 case CTF_FIELD_CLASS_TYPE_ENUM
:
638 _ctf_field_class_enum_destroy((void *) fc
);
640 case CTF_FIELD_CLASS_TYPE_FLOAT
:
641 _ctf_field_class_float_destroy((void *) fc
);
643 case CTF_FIELD_CLASS_TYPE_STRING
:
644 _ctf_field_class_string_destroy((void *) fc
);
646 case CTF_FIELD_CLASS_TYPE_STRUCT
:
647 _ctf_field_class_struct_destroy((void *) fc
);
649 case CTF_FIELD_CLASS_TYPE_ARRAY
:
650 _ctf_field_class_array_destroy((void *) fc
);
652 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
653 _ctf_field_class_sequence_destroy((void *) fc
);
655 case CTF_FIELD_CLASS_TYPE_VARIANT
:
656 _ctf_field_class_variant_destroy((void *) fc
);
664 void ctf_field_class_enum_append_mapping(struct ctf_field_class_enum
*fc
,
665 const char *label
, uint64_t u_lower
, uint64_t u_upper
)
667 struct ctf_field_class_enum_mapping
*mapping
;
671 g_array_set_size(fc
->mappings
, fc
->mappings
->len
+ 1);
673 mapping
= &g_array_index(fc
->mappings
,
674 struct ctf_field_class_enum_mapping
, fc
->mappings
->len
- 1);
675 _ctf_field_class_enum_mapping_init(mapping
);
676 g_string_assign(mapping
->label
, label
);
677 mapping
->range
.lower
.u
= u_lower
;
678 mapping
->range
.upper
.u
= u_upper
;
682 struct ctf_field_class_enum_mapping
*ctf_field_class_enum_borrow_mapping_by_index(
683 struct ctf_field_class_enum
*fc
, uint64_t index
)
686 BT_ASSERT(index
< fc
->mappings
->len
);
687 return &g_array_index(fc
->mappings
, struct ctf_field_class_enum_mapping
,
692 struct ctf_named_field_class
*ctf_field_class_struct_borrow_member_by_index(
693 struct ctf_field_class_struct
*fc
, uint64_t index
)
696 BT_ASSERT(index
< fc
->members
->len
);
697 return &g_array_index(fc
->members
, struct ctf_named_field_class
,
702 struct ctf_named_field_class
*ctf_field_class_struct_borrow_member_by_name(
703 struct ctf_field_class_struct
*fc
, const char *name
)
706 struct ctf_named_field_class
*ret_named_fc
= NULL
;
711 for (i
= 0; i
< fc
->members
->len
; i
++) {
712 struct ctf_named_field_class
*named_fc
=
713 ctf_field_class_struct_borrow_member_by_index(fc
, i
);
715 if (strcmp(name
, named_fc
->name
->str
) == 0) {
716 ret_named_fc
= named_fc
;
726 struct ctf_field_class
*ctf_field_class_struct_borrow_member_field_class_by_name(
727 struct ctf_field_class_struct
*struct_fc
, const char *name
)
729 struct ctf_named_field_class
*named_fc
= NULL
;
730 struct ctf_field_class
*fc
= NULL
;
736 named_fc
= ctf_field_class_struct_borrow_member_by_name(struct_fc
, name
);
748 struct ctf_field_class_int
*
749 ctf_field_class_struct_borrow_member_int_field_class_by_name(
750 struct ctf_field_class_struct
*struct_fc
, const char *name
)
752 struct ctf_field_class_int
*int_fc
= NULL
;
755 ctf_field_class_struct_borrow_member_field_class_by_name(
761 if (int_fc
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
&&
762 int_fc
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
773 void ctf_field_class_struct_append_member(struct ctf_field_class_struct
*fc
,
774 const char *name
, struct ctf_field_class
*member_fc
)
776 struct ctf_named_field_class
*named_fc
;
780 g_array_set_size(fc
->members
, fc
->members
->len
+ 1);
782 named_fc
= &g_array_index(fc
->members
, struct ctf_named_field_class
,
783 fc
->members
->len
- 1);
784 _ctf_named_field_class_init(named_fc
);
785 g_string_assign(named_fc
->name
, name
);
786 named_fc
->fc
= member_fc
;
788 if (member_fc
->alignment
> fc
->base
.alignment
) {
789 fc
->base
.alignment
= member_fc
->alignment
;
794 struct ctf_named_field_class
*ctf_field_class_variant_borrow_option_by_index(
795 struct ctf_field_class_variant
*fc
, uint64_t index
)
798 BT_ASSERT(index
< fc
->options
->len
);
799 return &g_array_index(fc
->options
, struct ctf_named_field_class
,
804 struct ctf_named_field_class
*ctf_field_class_variant_borrow_option_by_name(
805 struct ctf_field_class_variant
*fc
, const char *name
)
808 struct ctf_named_field_class
*ret_named_fc
= NULL
;
813 for (i
= 0; i
< fc
->options
->len
; i
++) {
814 struct ctf_named_field_class
*named_fc
=
815 ctf_field_class_variant_borrow_option_by_index(fc
, i
);
817 if (strcmp(name
, named_fc
->name
->str
) == 0) {
818 ret_named_fc
= named_fc
;
828 struct ctf_field_class_variant_range
*
829 ctf_field_class_variant_borrow_range_by_index(
830 struct ctf_field_class_variant
*fc
, uint64_t index
)
833 BT_ASSERT(index
< fc
->ranges
->len
);
834 return &g_array_index(fc
->ranges
, struct ctf_field_class_variant_range
,
839 void ctf_field_class_variant_append_option(struct ctf_field_class_variant
*fc
,
840 const char *name
, struct ctf_field_class
*option_fc
)
842 struct ctf_named_field_class
*named_fc
;
846 g_array_set_size(fc
->options
, fc
->options
->len
+ 1);
848 named_fc
= &g_array_index(fc
->options
, struct ctf_named_field_class
,
849 fc
->options
->len
- 1);
850 _ctf_named_field_class_init(named_fc
);
851 g_string_assign(named_fc
->name
, name
);
852 named_fc
->fc
= option_fc
;
856 void ctf_field_class_variant_set_tag_field_class(
857 struct ctf_field_class_variant
*fc
,
858 struct ctf_field_class_enum
*tag_fc
)
866 for (option_i
= 0; option_i
< fc
->options
->len
; option_i
++) {
868 struct ctf_named_field_class
*named_fc
=
869 ctf_field_class_variant_borrow_option_by_index(
872 for (mapping_i
= 0; mapping_i
< tag_fc
->mappings
->len
;
874 struct ctf_field_class_enum_mapping
*mapping
=
875 ctf_field_class_enum_borrow_mapping_by_index(
878 if (strcmp(named_fc
->name
->str
,
879 mapping
->label
->str
) == 0) {
880 struct ctf_field_class_variant_range range
;
882 range
.range
= mapping
->range
;
883 range
.option_index
= option_i
;
884 g_array_append_val(fc
->ranges
, range
);
891 struct ctf_field_class
*ctf_field_class_compound_borrow_field_class_by_index(
892 struct ctf_field_class
*comp_fc
, uint64_t index
)
894 struct ctf_field_class
*fc
= NULL
;
896 switch (comp_fc
->type
) {
897 case CTF_FIELD_CLASS_TYPE_STRUCT
:
899 struct ctf_named_field_class
*named_fc
=
900 ctf_field_class_struct_borrow_member_by_index(
901 (void *) comp_fc
, index
);
907 case CTF_FIELD_CLASS_TYPE_VARIANT
:
909 struct ctf_named_field_class
*named_fc
=
910 ctf_field_class_variant_borrow_option_by_index(
911 (void *) comp_fc
, index
);
917 case CTF_FIELD_CLASS_TYPE_ARRAY
:
918 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
920 struct ctf_field_class_array_base
*array_fc
= (void *) comp_fc
;
922 fc
= array_fc
->elem_fc
;
933 uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class
*fc
)
935 uint64_t field_count
;
938 case CTF_FIELD_CLASS_TYPE_STRUCT
:
940 struct ctf_field_class_struct
*struct_fc
= (void *) fc
;
942 field_count
= struct_fc
->members
->len
;
945 case CTF_FIELD_CLASS_TYPE_VARIANT
:
947 struct ctf_field_class_variant
*var_fc
= (void *) fc
;
949 field_count
= var_fc
->options
->len
;
952 case CTF_FIELD_CLASS_TYPE_ARRAY
:
953 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
955 * Array and sequence types always contain a single
956 * member (the element type).
968 int64_t ctf_field_class_compound_get_field_class_index_from_name(
969 struct ctf_field_class
*fc
, const char *name
)
971 int64_t ret_index
= -1;
975 case CTF_FIELD_CLASS_TYPE_STRUCT
:
977 struct ctf_field_class_struct
*struct_fc
= (void *) fc
;
979 for (i
= 0; i
< struct_fc
->members
->len
; i
++) {
980 struct ctf_named_field_class
*named_fc
=
981 ctf_field_class_struct_borrow_member_by_index(
984 if (strcmp(name
, named_fc
->name
->str
) == 0) {
985 ret_index
= (int64_t) i
;
992 case CTF_FIELD_CLASS_TYPE_VARIANT
:
994 struct ctf_field_class_variant
*var_fc
= (void *) fc
;
996 for (i
= 0; i
< var_fc
->options
->len
; i
++) {
997 struct ctf_named_field_class
*named_fc
=
998 ctf_field_class_variant_borrow_option_by_index(
1001 if (strcmp(name
, named_fc
->name
->str
) == 0) {
1002 ret_index
= (int64_t) i
;
1018 void ctf_field_path_append_index(struct ctf_field_path
*fp
, int64_t index
)
1021 g_array_append_val(fp
->path
, index
);
1025 int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path
*fp
,
1029 BT_ASSERT(index
< fp
->path
->len
);
1030 return g_array_index(fp
->path
, int64_t, index
);
1034 void ctf_field_path_clear(struct ctf_field_path
*fp
)
1037 g_array_set_size(fp
->path
, 0);
1041 const char *ctf_scope_string(enum ctf_scope scope
)
1044 case CTF_SCOPE_PACKET_HEADER
:
1045 return "CTF_SCOPE_PACKET_HEADER";
1046 case CTF_SCOPE_PACKET_CONTEXT
:
1047 return "CTF_SCOPE_PACKET_CONTEXT";
1048 case CTF_SCOPE_EVENT_HEADER
:
1049 return "CTF_SCOPE_EVENT_HEADER";
1050 case CTF_SCOPE_EVENT_COMMON_CONTEXT
:
1051 return "CTF_SCOPE_EVENT_COMMON_CONTEXT";
1052 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT
:
1053 return "CTF_SCOPE_EVENT_SPECIFIC_CONTEXT";
1054 case CTF_SCOPE_EVENT_PAYLOAD
:
1055 return "CTF_SCOPE_EVENT_PAYLOAD";
1062 GString
*ctf_field_path_string(struct ctf_field_path
*path
)
1064 GString
*str
= g_string_new(NULL
);
1073 g_string_append_printf(str
, "[%s", ctf_scope_string(path
->root
));
1075 for (i
= 0; i
< path
->path
->len
; i
++) {
1076 g_string_append_printf(str
, ", %" PRId64
,
1077 ctf_field_path_borrow_index_by_index(path
, i
));
1080 g_string_append(str
, "]");
1087 struct ctf_field_class
*ctf_field_path_borrow_field_class(
1088 struct ctf_field_path
*field_path
,
1089 struct ctf_trace_class
*tc
,
1090 struct ctf_stream_class
*sc
,
1091 struct ctf_event_class
*ec
)
1094 struct ctf_field_class
*fc
;
1096 switch (field_path
->root
) {
1097 case CTF_SCOPE_PACKET_HEADER
:
1098 fc
= tc
->packet_header_fc
;
1100 case CTF_SCOPE_PACKET_CONTEXT
:
1101 fc
= sc
->packet_context_fc
;
1103 case CTF_SCOPE_EVENT_HEADER
:
1104 fc
= sc
->event_header_fc
;
1106 case CTF_SCOPE_EVENT_COMMON_CONTEXT
:
1107 fc
= sc
->event_common_context_fc
;
1109 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT
:
1110 fc
= ec
->spec_context_fc
;
1112 case CTF_SCOPE_EVENT_PAYLOAD
:
1113 fc
= ec
->payload_fc
;
1121 for (i
= 0; i
< field_path
->path
->len
; i
++) {
1122 int64_t child_index
=
1123 ctf_field_path_borrow_index_by_index(field_path
, i
);
1124 struct ctf_field_class
*child_fc
=
1125 ctf_field_class_compound_borrow_field_class_by_index(
1127 BT_ASSERT(child_fc
);
1136 struct ctf_field_class
*ctf_field_class_copy(struct ctf_field_class
*fc
);
1139 void ctf_field_class_bit_array_copy_content(
1140 struct ctf_field_class_bit_array
*dst_fc
,
1141 struct ctf_field_class_bit_array
*src_fc
)
1145 dst_fc
->byte_order
= src_fc
->byte_order
;
1146 dst_fc
->size
= src_fc
->size
;
1150 void ctf_field_class_int_copy_content(
1151 struct ctf_field_class_int
*dst_fc
,
1152 struct ctf_field_class_int
*src_fc
)
1154 ctf_field_class_bit_array_copy_content((void *) dst_fc
, (void *) src_fc
);
1155 dst_fc
->meaning
= src_fc
->meaning
;
1156 dst_fc
->is_signed
= src_fc
->is_signed
;
1157 dst_fc
->disp_base
= src_fc
->disp_base
;
1158 dst_fc
->encoding
= src_fc
->encoding
;
1159 dst_fc
->mapped_clock_class
= src_fc
->mapped_clock_class
;
1160 dst_fc
->storing_index
= src_fc
->storing_index
;
1164 struct ctf_field_class_int
*_ctf_field_class_int_copy(
1165 struct ctf_field_class_int
*fc
)
1167 struct ctf_field_class_int
*copy_fc
= ctf_field_class_int_create();
1170 ctf_field_class_int_copy_content(copy_fc
, fc
);
1175 struct ctf_field_class_enum
*_ctf_field_class_enum_copy(
1176 struct ctf_field_class_enum
*fc
)
1178 struct ctf_field_class_enum
*copy_fc
= ctf_field_class_enum_create();
1182 ctf_field_class_int_copy_content((void *) copy_fc
, (void *) fc
);
1184 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
1185 struct ctf_field_class_enum_mapping
*mapping
=
1186 &g_array_index(fc
->mappings
,
1187 struct ctf_field_class_enum_mapping
, i
);
1189 ctf_field_class_enum_append_mapping(copy_fc
, mapping
->label
->str
,
1190 mapping
->range
.lower
.u
, mapping
->range
.upper
.u
);
1197 struct ctf_field_class_float
*_ctf_field_class_float_copy(
1198 struct ctf_field_class_float
*fc
)
1200 struct ctf_field_class_float
*copy_fc
= ctf_field_class_float_create();
1203 ctf_field_class_bit_array_copy_content((void *) copy_fc
, (void *) fc
);
1208 struct ctf_field_class_string
*_ctf_field_class_string_copy(
1209 struct ctf_field_class_string
*fc
)
1211 struct ctf_field_class_string
*copy_fc
= ctf_field_class_string_create();
1218 struct ctf_field_class_struct
*_ctf_field_class_struct_copy(
1219 struct ctf_field_class_struct
*fc
)
1221 struct ctf_field_class_struct
*copy_fc
= ctf_field_class_struct_create();
1226 for (i
= 0; i
< fc
->members
->len
; i
++) {
1227 struct ctf_named_field_class
*named_fc
=
1228 &g_array_index(fc
->members
,
1229 struct ctf_named_field_class
, i
);
1231 ctf_field_class_struct_append_member(copy_fc
,
1232 named_fc
->name
->str
,
1233 ctf_field_class_copy(named_fc
->fc
));
1240 void ctf_field_path_copy_content(struct ctf_field_path
*dst_fp
,
1241 struct ctf_field_path
*src_fp
)
1247 dst_fp
->root
= src_fp
->root
;
1248 ctf_field_path_clear(dst_fp
);
1250 for (i
= 0; i
< src_fp
->path
->len
; i
++) {
1251 int64_t index
= ctf_field_path_borrow_index_by_index(
1254 ctf_field_path_append_index(dst_fp
, index
);
1259 struct ctf_field_class_variant
*_ctf_field_class_variant_copy(
1260 struct ctf_field_class_variant
*fc
)
1262 struct ctf_field_class_variant
*copy_fc
=
1263 ctf_field_class_variant_create();
1268 for (i
= 0; i
< fc
->options
->len
; i
++) {
1269 struct ctf_named_field_class
*named_fc
=
1270 &g_array_index(fc
->options
,
1271 struct ctf_named_field_class
, i
);
1273 ctf_field_class_variant_append_option(copy_fc
,
1274 named_fc
->name
->str
,
1275 ctf_field_class_copy(named_fc
->fc
));
1278 for (i
= 0; i
< fc
->ranges
->len
; i
++) {
1279 struct ctf_field_class_variant_range
*range
=
1280 &g_array_index(fc
->ranges
,
1281 struct ctf_field_class_variant_range
, i
);
1283 g_array_append_val(copy_fc
->ranges
, *range
);
1286 ctf_field_path_copy_content(©_fc
->tag_path
, &fc
->tag_path
);
1287 g_string_assign(copy_fc
->tag_ref
, fc
->tag_ref
->str
);
1288 copy_fc
->stored_tag_index
= fc
->stored_tag_index
;
1293 void ctf_field_class_array_base_copy_content(
1294 struct ctf_field_class_array_base
*dst_fc
,
1295 struct ctf_field_class_array_base
*src_fc
)
1299 dst_fc
->elem_fc
= ctf_field_class_copy(src_fc
->elem_fc
);
1300 dst_fc
->is_text
= src_fc
->is_text
;
1304 struct ctf_field_class_array
*_ctf_field_class_array_copy(
1305 struct ctf_field_class_array
*fc
)
1307 struct ctf_field_class_array
*copy_fc
= ctf_field_class_array_create();
1310 ctf_field_class_array_base_copy_content((void *) copy_fc
, (void *) fc
);
1311 copy_fc
->length
= fc
->length
;
1316 struct ctf_field_class_sequence
*_ctf_field_class_sequence_copy(
1317 struct ctf_field_class_sequence
*fc
)
1319 struct ctf_field_class_sequence
*copy_fc
=
1320 ctf_field_class_sequence_create();
1323 ctf_field_class_array_base_copy_content((void *) copy_fc
, (void *) fc
);
1324 ctf_field_path_copy_content(©_fc
->length_path
, &fc
->length_path
);
1325 g_string_assign(copy_fc
->length_ref
, fc
->length_ref
->str
);
1326 copy_fc
->stored_length_index
= fc
->stored_length_index
;
1331 struct ctf_field_class
*ctf_field_class_copy(struct ctf_field_class
*fc
)
1333 struct ctf_field_class
*copy_fc
= NULL
;
1340 * Translation should not have happened yet.
1342 BT_ASSERT(!fc
->ir_fc
);
1345 case CTF_FIELD_CLASS_TYPE_INT
:
1346 copy_fc
= (void *) _ctf_field_class_int_copy((void *) fc
);
1348 case CTF_FIELD_CLASS_TYPE_ENUM
:
1349 copy_fc
= (void *) _ctf_field_class_enum_copy((void *) fc
);
1351 case CTF_FIELD_CLASS_TYPE_FLOAT
:
1352 copy_fc
= (void *) _ctf_field_class_float_copy((void *) fc
);
1354 case CTF_FIELD_CLASS_TYPE_STRING
:
1355 copy_fc
= (void *) _ctf_field_class_string_copy((void *) fc
);
1357 case CTF_FIELD_CLASS_TYPE_STRUCT
:
1358 copy_fc
= (void *) _ctf_field_class_struct_copy((void *) fc
);
1360 case CTF_FIELD_CLASS_TYPE_ARRAY
:
1361 copy_fc
= (void *) _ctf_field_class_array_copy((void *) fc
);
1363 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
1364 copy_fc
= (void *) _ctf_field_class_sequence_copy((void *) fc
);
1366 case CTF_FIELD_CLASS_TYPE_VARIANT
:
1367 copy_fc
= (void *) _ctf_field_class_variant_copy((void *) fc
);
1373 copy_fc
->type
= fc
->type
;
1374 copy_fc
->alignment
= fc
->alignment
;
1375 copy_fc
->in_ir
= fc
->in_ir
;
1382 struct ctf_event_class
*ctf_event_class_create(void)
1384 struct ctf_event_class
*ec
= g_new0(struct ctf_event_class
, 1);
1387 ec
->name
= g_string_new(NULL
);
1388 BT_ASSERT(ec
->name
);
1389 ec
->emf_uri
= g_string_new(NULL
);
1390 BT_ASSERT(ec
->emf_uri
);
1396 void ctf_event_class_destroy(struct ctf_event_class
*ec
)
1403 g_string_free(ec
->name
, TRUE
);
1407 g_string_free(ec
->emf_uri
, TRUE
);
1410 ctf_field_class_destroy(ec
->spec_context_fc
);
1411 ctf_field_class_destroy(ec
->payload_fc
);
1416 struct ctf_stream_class
*ctf_stream_class_create(void)
1418 struct ctf_stream_class
*sc
= g_new0(struct ctf_stream_class
, 1);
1421 sc
->event_classes
= g_ptr_array_new_with_free_func(
1422 (GDestroyNotify
) ctf_event_class_destroy
);
1423 BT_ASSERT(sc
->event_classes
);
1424 sc
->event_classes_by_id
= g_hash_table_new(g_direct_hash
,
1426 BT_ASSERT(sc
->event_classes_by_id
);
1431 void ctf_stream_class_destroy(struct ctf_stream_class
*sc
)
1437 if (sc
->event_classes
) {
1438 g_ptr_array_free(sc
->event_classes
, TRUE
);
1441 if (sc
->event_classes_by_id
) {
1442 g_hash_table_destroy(sc
->event_classes_by_id
);
1445 ctf_field_class_destroy(sc
->packet_context_fc
);
1446 ctf_field_class_destroy(sc
->event_header_fc
);
1447 ctf_field_class_destroy(sc
->event_common_context_fc
);
1452 void ctf_stream_class_append_event_class(struct ctf_stream_class
*sc
,
1453 struct ctf_event_class
*ec
)
1455 g_ptr_array_add(sc
->event_classes
, ec
);
1456 g_hash_table_insert(sc
->event_classes_by_id
,
1457 GUINT_TO_POINTER((guint
) ec
->id
), ec
);
1461 struct ctf_event_class
*ctf_stream_class_borrow_event_class_by_id(
1462 struct ctf_stream_class
*sc
, uint64_t type
)
1465 return g_hash_table_lookup(sc
->event_classes_by_id
,
1466 GUINT_TO_POINTER((guint
) type
));
1470 void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry
*entry
)
1473 entry
->name
= g_string_new(NULL
);
1474 BT_ASSERT(entry
->name
);
1475 entry
->value
.str
= g_string_new(NULL
);
1476 BT_ASSERT(entry
->value
.str
);
1480 void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry
*entry
)
1485 g_string_free(entry
->name
, TRUE
);
1488 if (entry
->value
.str
) {
1489 g_string_free(entry
->value
.str
, TRUE
);
1494 struct ctf_clock_class
*ctf_clock_class_create(void)
1496 struct ctf_clock_class
*cc
= g_new0(struct ctf_clock_class
, 1);
1499 cc
->name
= g_string_new(NULL
);
1500 BT_ASSERT(cc
->name
);
1501 cc
->description
= g_string_new(NULL
);
1502 BT_ASSERT(cc
->description
);
1507 void ctf_clock_class_destroy(struct ctf_clock_class
*cc
)
1514 g_string_free(cc
->name
, TRUE
);
1517 if (cc
->description
) {
1518 g_string_free(cc
->description
, TRUE
);
1521 bt_clock_class_put_ref(cc
->ir_cc
);
1526 struct ctf_trace_class
*ctf_trace_class_create(void)
1528 struct ctf_trace_class
*tc
= g_new0(struct ctf_trace_class
, 1);
1531 tc
->default_byte_order
= -1;
1532 tc
->clock_classes
= g_ptr_array_new_with_free_func(
1533 (GDestroyNotify
) ctf_clock_class_destroy
);
1534 BT_ASSERT(tc
->clock_classes
);
1535 tc
->stream_classes
= g_ptr_array_new_with_free_func(
1536 (GDestroyNotify
) ctf_stream_class_destroy
);
1537 BT_ASSERT(tc
->stream_classes
);
1538 tc
->env_entries
= g_array_new(FALSE
, TRUE
,
1539 sizeof(struct ctf_trace_class_env_entry
));
1544 void ctf_trace_class_destroy(struct ctf_trace_class
*tc
)
1550 ctf_field_class_destroy(tc
->packet_header_fc
);
1552 if (tc
->clock_classes
) {
1553 g_ptr_array_free(tc
->clock_classes
, TRUE
);
1556 if (tc
->stream_classes
) {
1557 g_ptr_array_free(tc
->stream_classes
, TRUE
);
1560 if (tc
->env_entries
) {
1563 for (i
= 0; i
< tc
->env_entries
->len
; i
++) {
1564 struct ctf_trace_class_env_entry
*entry
=
1565 &g_array_index(tc
->env_entries
,
1566 struct ctf_trace_class_env_entry
, i
);
1568 _ctf_trace_class_env_entry_fini(entry
);
1571 g_array_free(tc
->env_entries
, TRUE
);
1578 void ctf_trace_class_append_env_entry(struct ctf_trace_class
*tc
,
1579 const char *name
, enum ctf_trace_class_env_entry_type type
,
1580 const char *str_value
, int64_t i_value
)
1582 struct ctf_trace_class_env_entry
*entry
;
1586 g_array_set_size(tc
->env_entries
, tc
->env_entries
->len
+ 1);
1588 entry
= &g_array_index(tc
->env_entries
,
1589 struct ctf_trace_class_env_entry
, tc
->env_entries
->len
- 1);
1591 _ctf_trace_class_env_entry_init(entry
);
1592 g_string_assign(entry
->name
, name
);
1595 g_string_assign(entry
->value
.str
, str_value
);
1598 entry
->value
.i
= i_value
;
1602 struct ctf_stream_class
*ctf_trace_class_borrow_stream_class_by_id(
1603 struct ctf_trace_class
*tc
, uint64_t id
)
1606 struct ctf_stream_class
*ret_sc
= NULL
;
1610 for (i
= 0; i
< tc
->stream_classes
->len
; i
++) {
1611 struct ctf_stream_class
*sc
= tc
->stream_classes
->pdata
[i
];
1624 struct ctf_clock_class
*ctf_trace_class_borrow_clock_class_by_name(
1625 struct ctf_trace_class
*tc
, const char *name
)
1628 struct ctf_clock_class
*ret_cc
= NULL
;
1633 for (i
= 0; i
< tc
->clock_classes
->len
; i
++) {
1634 struct ctf_clock_class
*cc
= tc
->clock_classes
->pdata
[i
];
1636 BT_ASSERT(cc
->name
);
1637 if (strcmp(cc
->name
->str
, name
) == 0) {
1648 struct ctf_trace_class_env_entry
*ctf_trace_class_borrow_env_entry_by_index(
1649 struct ctf_trace_class
*tc
, uint64_t index
)
1652 BT_ASSERT(index
< tc
->env_entries
->len
);
1653 return &g_array_index(tc
->env_entries
, struct ctf_trace_class_env_entry
,
1658 struct ctf_trace_class_env_entry
*ctf_trace_class_borrow_env_entry_by_name(
1659 struct ctf_trace_class
*tc
, const char *name
)
1661 struct ctf_trace_class_env_entry
*ret_entry
= NULL
;
1667 for (i
= 0; i
< tc
->env_entries
->len
; i
++) {
1668 struct ctf_trace_class_env_entry
*env_entry
=
1669 ctf_trace_class_borrow_env_entry_by_index(tc
, i
);
1671 if (strcmp(env_entry
->name
->str
, name
) == 0) {
1672 ret_entry
= env_entry
;
1681 #endif /* _CTF_META_H */