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_UNKNOWN
= -1,
65 CTF_SCOPE_PACKET_HEADER
= 0,
66 CTF_SCOPE_PACKET_CONTEXT
,
67 CTF_SCOPE_EVENT_HEADER
,
68 CTF_SCOPE_EVENT_COMMON_CONTEXT
,
69 CTF_SCOPE_EVENT_SPECIFIC_CONTEXT
,
70 CTF_SCOPE_EVENT_PAYLOAD
,
73 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
{
89 enum ctf_field_class_type type
;
90 unsigned int alignment
;
94 /* Weak, set during translation. NULL if `in_ir` is false below. */
95 bt_field_class
*ir_fc
;
98 struct ctf_field_class_bit_array
{
99 struct ctf_field_class base
;
100 enum ctf_byte_order byte_order
;
104 struct ctf_field_class_int
{
105 struct ctf_field_class_bit_array base
;
106 enum ctf_field_class_meaning meaning
;
108 bt_field_class_integer_preferred_display_base disp_base
;
109 enum ctf_encoding encoding
;
110 int64_t storing_index
;
113 struct ctf_clock_class
*mapped_clock_class
;
128 struct ctf_field_class_enum_mapping
{
131 /* Array of `struct ctf_range` */
135 struct ctf_field_class_enum
{
136 struct ctf_field_class_int base
;
138 /* Array of `struct ctf_field_class_enum_mapping` */
142 struct ctf_field_class_float
{
143 struct ctf_field_class_bit_array base
;
146 struct ctf_field_class_string
{
147 struct ctf_field_class base
;
148 enum ctf_encoding encoding
;
151 struct ctf_named_field_class
{
152 /* Original name which can include a leading `_` */
155 /* Name as translated to trace IR (leading `_` removed) */
159 struct ctf_field_class
*fc
;
162 struct ctf_field_class_struct
{
163 struct ctf_field_class base
;
165 /* Array of `struct ctf_named_field_class` */
169 struct ctf_field_path
{
172 /* Array of `int64_t` */
176 struct ctf_field_class_variant_range
{
177 struct ctf_range range
;
178 uint64_t option_index
;
181 struct ctf_field_class_variant
{
182 struct ctf_field_class base
;
184 struct ctf_field_path tag_path
;
185 uint64_t stored_tag_index
;
187 /* Array of `struct ctf_named_field_class` */
190 /* Array of `struct ctf_field_class_variant_range` */
194 struct ctf_field_class_enum
*tag_fc
;
197 struct ctf_field_class_array_base
{
198 struct ctf_field_class base
;
199 struct ctf_field_class
*elem_fc
;
203 struct ctf_field_class_array
{
204 struct ctf_field_class_array_base base
;
205 enum ctf_field_class_meaning meaning
;
209 struct ctf_field_class_sequence
{
210 struct ctf_field_class_array_base base
;
212 struct ctf_field_path length_path
;
213 uint64_t stored_length_index
;
216 struct ctf_field_class_int
*length_fc
;
219 struct ctf_event_class
{
223 bt_event_class_log_level log_level
;
225 bool is_log_level_set
;
228 struct ctf_field_class
*spec_context_fc
;
231 struct ctf_field_class
*payload_fc
;
233 /* Weak, set during translation */
234 bt_event_class
*ir_ec
;
237 struct ctf_stream_class
{
240 bool packets_have_ts_begin
;
241 bool packets_have_ts_end
;
242 bool has_discarded_events
;
243 bool has_discarded_packets
;
244 bool discarded_events_have_default_cs
;
245 bool discarded_packets_have_default_cs
;
248 struct ctf_field_class
*packet_context_fc
;
251 struct ctf_field_class
*event_header_fc
;
254 struct ctf_field_class
*event_common_context_fc
;
256 /* Array of `struct ctf_event_class *`, owned by this */
257 GPtrArray
*event_classes
;
260 * Hash table mapping event class IDs to `struct ctf_event_class *`,
263 GHashTable
*event_classes_by_id
;
266 struct ctf_clock_class
*default_clock_class
;
268 /* Weak, set during translation */
269 bt_stream_class
*ir_sc
;
272 enum ctf_trace_class_env_entry_type
{
273 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT
,
274 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR
,
277 struct ctf_trace_class_env_entry
{
278 enum ctf_trace_class_env_entry_type type
;
287 struct ctf_trace_class
{
292 enum ctf_byte_order default_byte_order
;
295 struct ctf_field_class
*packet_header_fc
;
297 uint64_t stored_value_count
;
299 /* Array of `struct ctf_clock_class *` (owned by this) */
300 GPtrArray
*clock_classes
;
302 /* Array of `struct ctf_stream_class *` */
303 GPtrArray
*stream_classes
;
305 /* Array of `struct ctf_trace_class_env_entry` */
310 /* Weak, set during translation */
311 bt_trace_class
*ir_tc
;
315 void ctf_field_class_destroy(struct ctf_field_class
*fc
);
318 void _ctf_field_class_init(struct ctf_field_class
*fc
,
319 enum ctf_field_class_type type
, unsigned int alignment
)
323 fc
->alignment
= alignment
;
328 void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array
*fc
,
329 enum ctf_field_class_type type
)
331 _ctf_field_class_init((void *) fc
, type
, 1);
335 void _ctf_field_class_int_init(struct ctf_field_class_int
*fc
,
336 enum ctf_field_class_type type
)
338 _ctf_field_class_bit_array_init((void *) fc
, type
);
339 fc
->meaning
= CTF_FIELD_CLASS_MEANING_NONE
;
340 fc
->storing_index
= -1;
344 void ctf_field_path_init(struct ctf_field_path
*field_path
)
346 BT_ASSERT(field_path
);
347 field_path
->path
= g_array_new(FALSE
, TRUE
, sizeof(int64_t));
348 BT_ASSERT(field_path
->path
);
352 void ctf_field_path_fini(struct ctf_field_path
*field_path
)
354 BT_ASSERT(field_path
);
356 if (field_path
->path
) {
357 g_array_free(field_path
->path
, TRUE
);
362 void _ctf_named_field_class_init(struct ctf_named_field_class
*named_fc
)
365 named_fc
->name
= g_string_new(NULL
);
366 BT_ASSERT(named_fc
->name
);
367 named_fc
->orig_name
= g_string_new(NULL
);
368 BT_ASSERT(named_fc
->orig_name
);
372 void _ctf_named_field_class_fini(struct ctf_named_field_class
*named_fc
)
376 if (named_fc
->name
) {
377 g_string_free(named_fc
->name
, TRUE
);
380 if (named_fc
->orig_name
) {
381 g_string_free(named_fc
->orig_name
, TRUE
);
384 ctf_field_class_destroy(named_fc
->fc
);
388 void _ctf_field_class_enum_mapping_init(
389 struct ctf_field_class_enum_mapping
*mapping
)
392 mapping
->label
= g_string_new(NULL
);
393 BT_ASSERT(mapping
->label
);
394 mapping
->ranges
= g_array_new(FALSE
, TRUE
, sizeof(struct ctf_range
));
395 BT_ASSERT(mapping
->ranges
);
399 void _ctf_field_class_enum_mapping_fini(
400 struct ctf_field_class_enum_mapping
*mapping
)
404 if (mapping
->label
) {
405 g_string_free(mapping
->label
, TRUE
);
408 if (mapping
->ranges
) {
409 g_array_free(mapping
->ranges
, TRUE
);
414 struct ctf_field_class_int
*ctf_field_class_int_create(void)
416 struct ctf_field_class_int
*fc
= g_new0(struct ctf_field_class_int
, 1);
419 _ctf_field_class_int_init(fc
, CTF_FIELD_CLASS_TYPE_INT
);
424 struct ctf_field_class_float
*ctf_field_class_float_create(void)
426 struct ctf_field_class_float
*fc
=
427 g_new0(struct ctf_field_class_float
, 1);
430 _ctf_field_class_bit_array_init((void *) fc
, CTF_FIELD_CLASS_TYPE_FLOAT
);
435 struct ctf_field_class_string
*ctf_field_class_string_create(void)
437 struct ctf_field_class_string
*fc
=
438 g_new0(struct ctf_field_class_string
, 1);
441 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_STRING
, 8);
446 struct ctf_field_class_enum
*ctf_field_class_enum_create(void)
448 struct ctf_field_class_enum
*fc
= g_new0(struct ctf_field_class_enum
, 1);
451 _ctf_field_class_int_init((void *) fc
, CTF_FIELD_CLASS_TYPE_ENUM
);
452 fc
->mappings
= g_array_new(FALSE
, TRUE
,
453 sizeof(struct ctf_field_class_enum_mapping
));
454 BT_ASSERT(fc
->mappings
);
459 struct ctf_field_class_struct
*ctf_field_class_struct_create(void)
461 struct ctf_field_class_struct
*fc
=
462 g_new0(struct ctf_field_class_struct
, 1);
465 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_STRUCT
, 1);
466 fc
->members
= g_array_new(FALSE
, TRUE
,
467 sizeof(struct ctf_named_field_class
));
468 BT_ASSERT(fc
->members
);
469 fc
->base
.is_compound
= true;
474 struct ctf_field_class_variant
*ctf_field_class_variant_create(void)
476 struct ctf_field_class_variant
*fc
=
477 g_new0(struct ctf_field_class_variant
, 1);
480 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_VARIANT
, 1);
481 fc
->options
= g_array_new(FALSE
, TRUE
,
482 sizeof(struct ctf_named_field_class
));
483 BT_ASSERT(fc
->options
);
484 fc
->ranges
= g_array_new(FALSE
, TRUE
,
485 sizeof(struct ctf_field_class_variant_range
));
486 BT_ASSERT(fc
->ranges
);
487 fc
->tag_ref
= g_string_new(NULL
);
488 BT_ASSERT(fc
->tag_ref
);
489 ctf_field_path_init(&fc
->tag_path
);
490 fc
->base
.is_compound
= true;
495 struct ctf_field_class_array
*ctf_field_class_array_create(void)
497 struct ctf_field_class_array
*fc
=
498 g_new0(struct ctf_field_class_array
, 1);
501 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_ARRAY
, 1);
502 fc
->base
.base
.is_compound
= true;
507 struct ctf_field_class_sequence
*ctf_field_class_sequence_create(void)
509 struct ctf_field_class_sequence
*fc
=
510 g_new0(struct ctf_field_class_sequence
, 1);
513 _ctf_field_class_init((void *) fc
, CTF_FIELD_CLASS_TYPE_SEQUENCE
, 1);
514 fc
->length_ref
= g_string_new(NULL
);
515 BT_ASSERT(fc
->length_ref
);
516 ctf_field_path_init(&fc
->length_path
);
517 fc
->base
.base
.is_compound
= true;
522 void _ctf_field_class_int_destroy(struct ctf_field_class_int
*fc
)
529 void _ctf_field_class_enum_destroy(struct ctf_field_class_enum
*fc
)
536 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
537 struct ctf_field_class_enum_mapping
*mapping
=
538 &g_array_index(fc
->mappings
,
539 struct ctf_field_class_enum_mapping
, i
);
541 _ctf_field_class_enum_mapping_fini(mapping
);
544 g_array_free(fc
->mappings
, TRUE
);
551 void _ctf_field_class_float_destroy(struct ctf_field_class_float
*fc
)
558 void _ctf_field_class_string_destroy(struct ctf_field_class_string
*fc
)
565 void _ctf_field_class_struct_destroy(struct ctf_field_class_struct
*fc
)
572 for (i
= 0; i
< fc
->members
->len
; i
++) {
573 struct ctf_named_field_class
*named_fc
=
574 &g_array_index(fc
->members
,
575 struct ctf_named_field_class
, i
);
577 _ctf_named_field_class_fini(named_fc
);
580 g_array_free(fc
->members
, TRUE
);
587 void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base
*fc
)
590 ctf_field_class_destroy(fc
->elem_fc
);
594 void _ctf_field_class_array_destroy(struct ctf_field_class_array
*fc
)
597 _ctf_field_class_array_base_fini((void *) fc
);
602 void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence
*fc
)
605 _ctf_field_class_array_base_fini((void *) fc
);
607 if (fc
->length_ref
) {
608 g_string_free(fc
->length_ref
, TRUE
);
611 ctf_field_path_fini(&fc
->length_path
);
616 void _ctf_field_class_variant_destroy(struct ctf_field_class_variant
*fc
)
623 for (i
= 0; i
< fc
->options
->len
; i
++) {
624 struct ctf_named_field_class
*named_fc
=
625 &g_array_index(fc
->options
,
626 struct ctf_named_field_class
, i
);
628 _ctf_named_field_class_fini(named_fc
);
631 g_array_free(fc
->options
, TRUE
);
635 g_array_free(fc
->ranges
, TRUE
);
639 g_string_free(fc
->tag_ref
, TRUE
);
642 ctf_field_path_fini(&fc
->tag_path
);
647 void ctf_field_class_destroy(struct ctf_field_class
*fc
)
654 case CTF_FIELD_CLASS_TYPE_INT
:
655 _ctf_field_class_int_destroy((void *) fc
);
657 case CTF_FIELD_CLASS_TYPE_ENUM
:
658 _ctf_field_class_enum_destroy((void *) fc
);
660 case CTF_FIELD_CLASS_TYPE_FLOAT
:
661 _ctf_field_class_float_destroy((void *) fc
);
663 case CTF_FIELD_CLASS_TYPE_STRING
:
664 _ctf_field_class_string_destroy((void *) fc
);
666 case CTF_FIELD_CLASS_TYPE_STRUCT
:
667 _ctf_field_class_struct_destroy((void *) fc
);
669 case CTF_FIELD_CLASS_TYPE_ARRAY
:
670 _ctf_field_class_array_destroy((void *) fc
);
672 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
673 _ctf_field_class_sequence_destroy((void *) fc
);
675 case CTF_FIELD_CLASS_TYPE_VARIANT
:
676 _ctf_field_class_variant_destroy((void *) fc
);
684 struct ctf_range
*ctf_field_class_enum_mapping_borrow_range_by_index(
685 struct ctf_field_class_enum_mapping
*mapping
, uint64_t index
)
688 BT_ASSERT(index
< mapping
->ranges
->len
);
689 return &g_array_index(mapping
->ranges
, struct ctf_range
, index
);
693 struct ctf_field_class_enum_mapping
*ctf_field_class_enum_borrow_mapping_by_index(
694 struct ctf_field_class_enum
*fc
, uint64_t index
)
697 BT_ASSERT(index
< fc
->mappings
->len
);
698 return &g_array_index(fc
->mappings
, struct ctf_field_class_enum_mapping
,
703 struct ctf_field_class_enum_mapping
*ctf_field_class_enum_borrow_mapping_by_label(
704 struct ctf_field_class_enum
*fc
, const char *label
)
706 struct ctf_field_class_enum_mapping
*ret_mapping
= NULL
;
712 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
713 struct ctf_field_class_enum_mapping
*mapping
=
714 ctf_field_class_enum_borrow_mapping_by_index(fc
, i
);
716 if (strcmp(mapping
->label
->str
, label
) == 0) {
717 ret_mapping
= mapping
;
727 void ctf_field_class_enum_map_range(struct ctf_field_class_enum
*fc
,
728 const char *label
, uint64_t u_lower
, uint64_t u_upper
)
730 struct ctf_field_class_enum_mapping
*mapping
= NULL
;
731 struct ctf_range range
= {
740 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
741 mapping
= ctf_field_class_enum_borrow_mapping_by_index(
744 if (strcmp(mapping
->label
->str
, label
) == 0) {
749 if (i
== fc
->mappings
->len
) {
754 g_array_set_size(fc
->mappings
, fc
->mappings
->len
+ 1);
755 mapping
= ctf_field_class_enum_borrow_mapping_by_index(
756 fc
, fc
->mappings
->len
- 1);
757 _ctf_field_class_enum_mapping_init(mapping
);
758 g_string_assign(mapping
->label
, label
);
761 g_array_append_val(mapping
->ranges
, range
);
765 struct ctf_named_field_class
*ctf_field_class_struct_borrow_member_by_index(
766 struct ctf_field_class_struct
*fc
, uint64_t index
)
769 BT_ASSERT(index
< fc
->members
->len
);
770 return &g_array_index(fc
->members
, struct ctf_named_field_class
,
775 struct ctf_named_field_class
*ctf_field_class_struct_borrow_member_by_name(
776 struct ctf_field_class_struct
*fc
, const char *name
)
779 struct ctf_named_field_class
*ret_named_fc
= NULL
;
784 for (i
= 0; i
< fc
->members
->len
; i
++) {
785 struct ctf_named_field_class
*named_fc
=
786 ctf_field_class_struct_borrow_member_by_index(fc
, i
);
788 if (strcmp(name
, named_fc
->name
->str
) == 0) {
789 ret_named_fc
= named_fc
;
799 struct ctf_field_class
*ctf_field_class_struct_borrow_member_field_class_by_name(
800 struct ctf_field_class_struct
*struct_fc
, const char *name
)
802 struct ctf_named_field_class
*named_fc
= NULL
;
803 struct ctf_field_class
*fc
= NULL
;
809 named_fc
= ctf_field_class_struct_borrow_member_by_name(struct_fc
, name
);
821 struct ctf_field_class_int
*
822 ctf_field_class_struct_borrow_member_int_field_class_by_name(
823 struct ctf_field_class_struct
*struct_fc
, const char *name
)
825 struct ctf_field_class_int
*int_fc
= NULL
;
828 ctf_field_class_struct_borrow_member_field_class_by_name(
834 if (int_fc
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_INT
&&
835 int_fc
->base
.base
.type
!= CTF_FIELD_CLASS_TYPE_ENUM
) {
845 void _ctf_named_field_class_unescape_orig_name(
846 struct ctf_named_field_class
*named_fc
)
848 const char *name
= named_fc
->orig_name
->str
;
850 if (name
[0] == '_') {
854 g_string_assign(named_fc
->name
, name
);
858 void ctf_field_class_struct_append_member(struct ctf_field_class_struct
*fc
,
859 const char *orig_name
, struct ctf_field_class
*member_fc
)
861 struct ctf_named_field_class
*named_fc
;
864 BT_ASSERT(orig_name
);
865 g_array_set_size(fc
->members
, fc
->members
->len
+ 1);
867 named_fc
= &g_array_index(fc
->members
, struct ctf_named_field_class
,
868 fc
->members
->len
- 1);
869 _ctf_named_field_class_init(named_fc
);
870 g_string_assign(named_fc
->orig_name
, orig_name
);
871 _ctf_named_field_class_unescape_orig_name(named_fc
);
872 named_fc
->fc
= member_fc
;
874 if (member_fc
->alignment
> fc
->base
.alignment
) {
875 fc
->base
.alignment
= member_fc
->alignment
;
880 struct ctf_named_field_class
*ctf_field_class_variant_borrow_option_by_index(
881 struct ctf_field_class_variant
*fc
, uint64_t index
)
884 BT_ASSERT(index
< fc
->options
->len
);
885 return &g_array_index(fc
->options
, struct ctf_named_field_class
,
890 struct ctf_named_field_class
*ctf_field_class_variant_borrow_option_by_name(
891 struct ctf_field_class_variant
*fc
, const char *name
)
894 struct ctf_named_field_class
*ret_named_fc
= NULL
;
899 for (i
= 0; i
< fc
->options
->len
; i
++) {
900 struct ctf_named_field_class
*named_fc
=
901 ctf_field_class_variant_borrow_option_by_index(fc
, i
);
903 if (strcmp(name
, named_fc
->name
->str
) == 0) {
904 ret_named_fc
= named_fc
;
914 struct ctf_field_class_variant_range
*
915 ctf_field_class_variant_borrow_range_by_index(
916 struct ctf_field_class_variant
*fc
, uint64_t index
)
919 BT_ASSERT(index
< fc
->ranges
->len
);
920 return &g_array_index(fc
->ranges
, struct ctf_field_class_variant_range
,
925 void ctf_field_class_variant_append_option(struct ctf_field_class_variant
*fc
,
926 const char *orig_name
, struct ctf_field_class
*option_fc
)
928 struct ctf_named_field_class
*named_fc
;
931 BT_ASSERT(orig_name
);
932 g_array_set_size(fc
->options
, fc
->options
->len
+ 1);
934 named_fc
= &g_array_index(fc
->options
, struct ctf_named_field_class
,
935 fc
->options
->len
- 1);
936 _ctf_named_field_class_init(named_fc
);
937 g_string_assign(named_fc
->orig_name
, orig_name
);
938 _ctf_named_field_class_unescape_orig_name(named_fc
);
939 named_fc
->fc
= option_fc
;
943 void ctf_field_class_variant_set_tag_field_class(
944 struct ctf_field_class_variant
*fc
,
945 struct ctf_field_class_enum
*tag_fc
)
953 for (option_i
= 0; option_i
< fc
->options
->len
; option_i
++) {
955 struct ctf_named_field_class
*named_fc
=
956 ctf_field_class_variant_borrow_option_by_index(
958 struct ctf_field_class_enum_mapping
*mapping
;
960 mapping
= ctf_field_class_enum_borrow_mapping_by_label(
961 tag_fc
, named_fc
->orig_name
->str
);
966 for (range_i
= 0; range_i
< mapping
->ranges
->len
;
968 struct ctf_range
*range
=
969 ctf_field_class_enum_mapping_borrow_range_by_index(
971 struct ctf_field_class_variant_range var_range
;
973 var_range
.range
= *range
;
974 var_range
.option_index
= option_i
;
975 g_array_append_val(fc
->ranges
, var_range
);
981 struct ctf_field_class
*ctf_field_class_compound_borrow_field_class_by_index(
982 struct ctf_field_class
*comp_fc
, uint64_t index
)
984 struct ctf_field_class
*fc
= NULL
;
986 switch (comp_fc
->type
) {
987 case CTF_FIELD_CLASS_TYPE_STRUCT
:
989 struct ctf_named_field_class
*named_fc
=
990 ctf_field_class_struct_borrow_member_by_index(
991 (void *) comp_fc
, index
);
997 case CTF_FIELD_CLASS_TYPE_VARIANT
:
999 struct ctf_named_field_class
*named_fc
=
1000 ctf_field_class_variant_borrow_option_by_index(
1001 (void *) comp_fc
, index
);
1003 BT_ASSERT(named_fc
);
1007 case CTF_FIELD_CLASS_TYPE_ARRAY
:
1008 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
1010 struct ctf_field_class_array_base
*array_fc
= (void *) comp_fc
;
1012 fc
= array_fc
->elem_fc
;
1023 uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class
*fc
)
1025 uint64_t field_count
;
1028 case CTF_FIELD_CLASS_TYPE_STRUCT
:
1030 struct ctf_field_class_struct
*struct_fc
= (void *) fc
;
1032 field_count
= struct_fc
->members
->len
;
1035 case CTF_FIELD_CLASS_TYPE_VARIANT
:
1037 struct ctf_field_class_variant
*var_fc
= (void *) fc
;
1039 field_count
= var_fc
->options
->len
;
1042 case CTF_FIELD_CLASS_TYPE_ARRAY
:
1043 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
1045 * Array and sequence types always contain a single
1046 * member (the element type).
1058 int64_t ctf_field_class_compound_get_field_class_index_from_orig_name(
1059 struct ctf_field_class
*fc
, const char *orig_name
)
1061 int64_t ret_index
= -1;
1065 case CTF_FIELD_CLASS_TYPE_STRUCT
:
1067 struct ctf_field_class_struct
*struct_fc
= (void *) fc
;
1069 for (i
= 0; i
< struct_fc
->members
->len
; i
++) {
1070 struct ctf_named_field_class
*named_fc
=
1071 ctf_field_class_struct_borrow_member_by_index(
1074 if (strcmp(orig_name
, named_fc
->orig_name
->str
) == 0) {
1075 ret_index
= (int64_t) i
;
1082 case CTF_FIELD_CLASS_TYPE_VARIANT
:
1084 struct ctf_field_class_variant
*var_fc
= (void *) fc
;
1086 for (i
= 0; i
< var_fc
->options
->len
; i
++) {
1087 struct ctf_named_field_class
*named_fc
=
1088 ctf_field_class_variant_borrow_option_by_index(
1091 if (strcmp(orig_name
, named_fc
->orig_name
->str
) == 0) {
1092 ret_index
= (int64_t) i
;
1108 void ctf_field_path_append_index(struct ctf_field_path
*fp
, int64_t index
)
1111 g_array_append_val(fp
->path
, index
);
1115 int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path
*fp
,
1119 BT_ASSERT(index
< fp
->path
->len
);
1120 return g_array_index(fp
->path
, int64_t, index
);
1124 void ctf_field_path_clear(struct ctf_field_path
*fp
)
1127 g_array_set_size(fp
->path
, 0);
1131 const char *ctf_scope_string(enum ctf_scope scope
)
1134 case CTF_SCOPE_PACKET_HEADER
:
1135 return "PACKET_HEADER";
1136 case CTF_SCOPE_PACKET_CONTEXT
:
1137 return "PACKET_CONTEXT";
1138 case CTF_SCOPE_EVENT_HEADER
:
1139 return "EVENT_HEADER";
1140 case CTF_SCOPE_EVENT_COMMON_CONTEXT
:
1141 return "EVENT_COMMON_CONTEXT";
1142 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT
:
1143 return "EVENT_SPECIFIC_CONTEXT";
1144 case CTF_SCOPE_EVENT_PAYLOAD
:
1145 return "EVENT_PAYLOAD";
1152 GString
*ctf_field_path_string(struct ctf_field_path
*path
)
1154 GString
*str
= g_string_new(NULL
);
1163 g_string_append_printf(str
, "[%s", ctf_scope_string(path
->root
));
1165 for (i
= 0; i
< path
->path
->len
; i
++) {
1166 g_string_append_printf(str
, ", %" PRId64
,
1167 ctf_field_path_borrow_index_by_index(path
, i
));
1170 g_string_append(str
, "]");
1177 struct ctf_field_class
*ctf_field_path_borrow_field_class(
1178 struct ctf_field_path
*field_path
,
1179 struct ctf_trace_class
*tc
,
1180 struct ctf_stream_class
*sc
,
1181 struct ctf_event_class
*ec
)
1184 struct ctf_field_class
*fc
;
1186 switch (field_path
->root
) {
1187 case CTF_SCOPE_PACKET_HEADER
:
1188 fc
= tc
->packet_header_fc
;
1190 case CTF_SCOPE_PACKET_CONTEXT
:
1191 fc
= sc
->packet_context_fc
;
1193 case CTF_SCOPE_EVENT_HEADER
:
1194 fc
= sc
->event_header_fc
;
1196 case CTF_SCOPE_EVENT_COMMON_CONTEXT
:
1197 fc
= sc
->event_common_context_fc
;
1199 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT
:
1200 fc
= ec
->spec_context_fc
;
1202 case CTF_SCOPE_EVENT_PAYLOAD
:
1203 fc
= ec
->payload_fc
;
1211 for (i
= 0; i
< field_path
->path
->len
; i
++) {
1212 int64_t child_index
=
1213 ctf_field_path_borrow_index_by_index(field_path
, i
);
1214 struct ctf_field_class
*child_fc
=
1215 ctf_field_class_compound_borrow_field_class_by_index(
1217 BT_ASSERT(child_fc
);
1226 struct ctf_field_class
*ctf_field_class_copy(struct ctf_field_class
*fc
);
1229 void ctf_field_class_bit_array_copy_content(
1230 struct ctf_field_class_bit_array
*dst_fc
,
1231 struct ctf_field_class_bit_array
*src_fc
)
1235 dst_fc
->byte_order
= src_fc
->byte_order
;
1236 dst_fc
->size
= src_fc
->size
;
1240 void ctf_field_class_int_copy_content(
1241 struct ctf_field_class_int
*dst_fc
,
1242 struct ctf_field_class_int
*src_fc
)
1244 ctf_field_class_bit_array_copy_content((void *) dst_fc
, (void *) src_fc
);
1245 dst_fc
->meaning
= src_fc
->meaning
;
1246 dst_fc
->is_signed
= src_fc
->is_signed
;
1247 dst_fc
->disp_base
= src_fc
->disp_base
;
1248 dst_fc
->encoding
= src_fc
->encoding
;
1249 dst_fc
->mapped_clock_class
= src_fc
->mapped_clock_class
;
1250 dst_fc
->storing_index
= src_fc
->storing_index
;
1254 struct ctf_field_class_int
*_ctf_field_class_int_copy(
1255 struct ctf_field_class_int
*fc
)
1257 struct ctf_field_class_int
*copy_fc
= ctf_field_class_int_create();
1260 ctf_field_class_int_copy_content(copy_fc
, fc
);
1265 struct ctf_field_class_enum
*_ctf_field_class_enum_copy(
1266 struct ctf_field_class_enum
*fc
)
1268 struct ctf_field_class_enum
*copy_fc
= ctf_field_class_enum_create();
1272 ctf_field_class_int_copy_content((void *) copy_fc
, (void *) fc
);
1274 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
1277 struct ctf_field_class_enum_mapping
*mapping
=
1278 &g_array_index(fc
->mappings
,
1279 struct ctf_field_class_enum_mapping
, i
);
1281 for (range_i
= 0; range_i
< mapping
->ranges
->len
; range_i
++) {
1282 struct ctf_range
*range
=
1283 &g_array_index(mapping
->ranges
,
1284 struct ctf_range
, range_i
);
1286 ctf_field_class_enum_map_range(copy_fc
,
1287 mapping
->label
->str
, range
->lower
.u
,
1296 struct ctf_field_class_float
*_ctf_field_class_float_copy(
1297 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((void *) copy_fc
, (void *) fc
);
1307 struct ctf_field_class_string
*_ctf_field_class_string_copy(
1308 struct ctf_field_class_string
*fc
)
1310 struct ctf_field_class_string
*copy_fc
= ctf_field_class_string_create();
1317 struct ctf_field_class_struct
*_ctf_field_class_struct_copy(
1318 struct ctf_field_class_struct
*fc
)
1320 struct ctf_field_class_struct
*copy_fc
= ctf_field_class_struct_create();
1325 for (i
= 0; i
< fc
->members
->len
; i
++) {
1326 struct ctf_named_field_class
*named_fc
=
1327 &g_array_index(fc
->members
,
1328 struct ctf_named_field_class
, i
);
1330 ctf_field_class_struct_append_member(copy_fc
,
1331 named_fc
->name
->str
,
1332 ctf_field_class_copy(named_fc
->fc
));
1339 void ctf_field_path_copy_content(struct ctf_field_path
*dst_fp
,
1340 struct ctf_field_path
*src_fp
)
1346 dst_fp
->root
= src_fp
->root
;
1347 ctf_field_path_clear(dst_fp
);
1349 for (i
= 0; i
< src_fp
->path
->len
; i
++) {
1350 int64_t index
= ctf_field_path_borrow_index_by_index(
1353 ctf_field_path_append_index(dst_fp
, index
);
1358 struct ctf_field_class_variant
*_ctf_field_class_variant_copy(
1359 struct ctf_field_class_variant
*fc
)
1361 struct ctf_field_class_variant
*copy_fc
=
1362 ctf_field_class_variant_create();
1367 for (i
= 0; i
< fc
->options
->len
; i
++) {
1368 struct ctf_named_field_class
*named_fc
=
1369 &g_array_index(fc
->options
,
1370 struct ctf_named_field_class
, i
);
1372 ctf_field_class_variant_append_option(copy_fc
,
1373 named_fc
->name
->str
,
1374 ctf_field_class_copy(named_fc
->fc
));
1377 for (i
= 0; i
< fc
->ranges
->len
; i
++) {
1378 struct ctf_field_class_variant_range
*range
=
1379 &g_array_index(fc
->ranges
,
1380 struct ctf_field_class_variant_range
, i
);
1382 g_array_append_val(copy_fc
->ranges
, *range
);
1385 ctf_field_path_copy_content(©_fc
->tag_path
, &fc
->tag_path
);
1386 g_string_assign(copy_fc
->tag_ref
, fc
->tag_ref
->str
);
1387 copy_fc
->stored_tag_index
= fc
->stored_tag_index
;
1392 void ctf_field_class_array_base_copy_content(
1393 struct ctf_field_class_array_base
*dst_fc
,
1394 struct ctf_field_class_array_base
*src_fc
)
1398 dst_fc
->elem_fc
= ctf_field_class_copy(src_fc
->elem_fc
);
1399 dst_fc
->is_text
= src_fc
->is_text
;
1403 struct ctf_field_class_array
*_ctf_field_class_array_copy(
1404 struct ctf_field_class_array
*fc
)
1406 struct ctf_field_class_array
*copy_fc
= ctf_field_class_array_create();
1409 ctf_field_class_array_base_copy_content((void *) copy_fc
, (void *) fc
);
1410 copy_fc
->length
= fc
->length
;
1415 struct ctf_field_class_sequence
*_ctf_field_class_sequence_copy(
1416 struct ctf_field_class_sequence
*fc
)
1418 struct ctf_field_class_sequence
*copy_fc
=
1419 ctf_field_class_sequence_create();
1422 ctf_field_class_array_base_copy_content((void *) copy_fc
, (void *) fc
);
1423 ctf_field_path_copy_content(©_fc
->length_path
, &fc
->length_path
);
1424 g_string_assign(copy_fc
->length_ref
, fc
->length_ref
->str
);
1425 copy_fc
->stored_length_index
= fc
->stored_length_index
;
1430 struct ctf_field_class
*ctf_field_class_copy(struct ctf_field_class
*fc
)
1432 struct ctf_field_class
*copy_fc
= NULL
;
1439 * Translation should not have happened yet.
1441 BT_ASSERT(!fc
->ir_fc
);
1444 case CTF_FIELD_CLASS_TYPE_INT
:
1445 copy_fc
= (void *) _ctf_field_class_int_copy((void *) fc
);
1447 case CTF_FIELD_CLASS_TYPE_ENUM
:
1448 copy_fc
= (void *) _ctf_field_class_enum_copy((void *) fc
);
1450 case CTF_FIELD_CLASS_TYPE_FLOAT
:
1451 copy_fc
= (void *) _ctf_field_class_float_copy((void *) fc
);
1453 case CTF_FIELD_CLASS_TYPE_STRING
:
1454 copy_fc
= (void *) _ctf_field_class_string_copy((void *) fc
);
1456 case CTF_FIELD_CLASS_TYPE_STRUCT
:
1457 copy_fc
= (void *) _ctf_field_class_struct_copy((void *) fc
);
1459 case CTF_FIELD_CLASS_TYPE_ARRAY
:
1460 copy_fc
= (void *) _ctf_field_class_array_copy((void *) fc
);
1462 case CTF_FIELD_CLASS_TYPE_SEQUENCE
:
1463 copy_fc
= (void *) _ctf_field_class_sequence_copy((void *) fc
);
1465 case CTF_FIELD_CLASS_TYPE_VARIANT
:
1466 copy_fc
= (void *) _ctf_field_class_variant_copy((void *) fc
);
1472 copy_fc
->type
= fc
->type
;
1473 copy_fc
->alignment
= fc
->alignment
;
1474 copy_fc
->in_ir
= fc
->in_ir
;
1481 struct ctf_event_class
*ctf_event_class_create(void)
1483 struct ctf_event_class
*ec
= g_new0(struct ctf_event_class
, 1);
1486 ec
->name
= g_string_new(NULL
);
1487 BT_ASSERT(ec
->name
);
1488 ec
->emf_uri
= g_string_new(NULL
);
1489 BT_ASSERT(ec
->emf_uri
);
1490 ec
->is_log_level_set
= false;
1495 void ctf_event_class_set_log_level(struct ctf_event_class
*ec
,
1496 enum bt_event_class_log_level log_level
)
1499 ec
->log_level
= log_level
;
1500 ec
->is_log_level_set
= true;
1504 void ctf_event_class_destroy(struct ctf_event_class
*ec
)
1511 g_string_free(ec
->name
, TRUE
);
1515 g_string_free(ec
->emf_uri
, TRUE
);
1518 ctf_field_class_destroy(ec
->spec_context_fc
);
1519 ctf_field_class_destroy(ec
->payload_fc
);
1524 struct ctf_stream_class
*ctf_stream_class_create(void)
1526 struct ctf_stream_class
*sc
= g_new0(struct ctf_stream_class
, 1);
1529 sc
->event_classes
= g_ptr_array_new_with_free_func(
1530 (GDestroyNotify
) ctf_event_class_destroy
);
1531 BT_ASSERT(sc
->event_classes
);
1532 sc
->event_classes_by_id
= g_hash_table_new(g_direct_hash
,
1534 BT_ASSERT(sc
->event_classes_by_id
);
1539 void ctf_stream_class_destroy(struct ctf_stream_class
*sc
)
1545 if (sc
->event_classes
) {
1546 g_ptr_array_free(sc
->event_classes
, TRUE
);
1549 if (sc
->event_classes_by_id
) {
1550 g_hash_table_destroy(sc
->event_classes_by_id
);
1553 ctf_field_class_destroy(sc
->packet_context_fc
);
1554 ctf_field_class_destroy(sc
->event_header_fc
);
1555 ctf_field_class_destroy(sc
->event_common_context_fc
);
1560 void ctf_stream_class_append_event_class(struct ctf_stream_class
*sc
,
1561 struct ctf_event_class
*ec
)
1563 g_ptr_array_add(sc
->event_classes
, ec
);
1564 g_hash_table_insert(sc
->event_classes_by_id
,
1565 GUINT_TO_POINTER((guint
) ec
->id
), ec
);
1569 struct ctf_event_class
*ctf_stream_class_borrow_event_class_by_id(
1570 struct ctf_stream_class
*sc
, uint64_t type
)
1573 return g_hash_table_lookup(sc
->event_classes_by_id
,
1574 GUINT_TO_POINTER((guint
) type
));
1578 void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry
*entry
)
1581 entry
->name
= g_string_new(NULL
);
1582 BT_ASSERT(entry
->name
);
1583 entry
->value
.str
= g_string_new(NULL
);
1584 BT_ASSERT(entry
->value
.str
);
1588 void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry
*entry
)
1593 g_string_free(entry
->name
, TRUE
);
1596 if (entry
->value
.str
) {
1597 g_string_free(entry
->value
.str
, TRUE
);
1602 struct ctf_clock_class
*ctf_clock_class_create(void)
1604 struct ctf_clock_class
*cc
= g_new0(struct ctf_clock_class
, 1);
1607 cc
->name
= g_string_new(NULL
);
1608 BT_ASSERT(cc
->name
);
1609 cc
->description
= g_string_new(NULL
);
1610 BT_ASSERT(cc
->description
);
1615 void ctf_clock_class_destroy(struct ctf_clock_class
*cc
)
1622 g_string_free(cc
->name
, TRUE
);
1625 if (cc
->description
) {
1626 g_string_free(cc
->description
, TRUE
);
1629 bt_clock_class_put_ref(cc
->ir_cc
);
1634 struct ctf_trace_class
*ctf_trace_class_create(void)
1636 struct ctf_trace_class
*tc
= g_new0(struct ctf_trace_class
, 1);
1639 tc
->default_byte_order
= -1;
1640 tc
->clock_classes
= g_ptr_array_new_with_free_func(
1641 (GDestroyNotify
) ctf_clock_class_destroy
);
1642 BT_ASSERT(tc
->clock_classes
);
1643 tc
->stream_classes
= g_ptr_array_new_with_free_func(
1644 (GDestroyNotify
) ctf_stream_class_destroy
);
1645 BT_ASSERT(tc
->stream_classes
);
1646 tc
->env_entries
= g_array_new(FALSE
, TRUE
,
1647 sizeof(struct ctf_trace_class_env_entry
));
1652 void ctf_trace_class_destroy(struct ctf_trace_class
*tc
)
1658 ctf_field_class_destroy(tc
->packet_header_fc
);
1660 if (tc
->clock_classes
) {
1661 g_ptr_array_free(tc
->clock_classes
, TRUE
);
1664 if (tc
->stream_classes
) {
1665 g_ptr_array_free(tc
->stream_classes
, TRUE
);
1668 if (tc
->env_entries
) {
1671 for (i
= 0; i
< tc
->env_entries
->len
; i
++) {
1672 struct ctf_trace_class_env_entry
*entry
=
1673 &g_array_index(tc
->env_entries
,
1674 struct ctf_trace_class_env_entry
, i
);
1676 _ctf_trace_class_env_entry_fini(entry
);
1679 g_array_free(tc
->env_entries
, TRUE
);
1686 void ctf_trace_class_append_env_entry(struct ctf_trace_class
*tc
,
1687 const char *name
, enum ctf_trace_class_env_entry_type type
,
1688 const char *str_value
, int64_t i_value
)
1690 struct ctf_trace_class_env_entry
*entry
;
1694 g_array_set_size(tc
->env_entries
, tc
->env_entries
->len
+ 1);
1696 entry
= &g_array_index(tc
->env_entries
,
1697 struct ctf_trace_class_env_entry
, tc
->env_entries
->len
- 1);
1699 _ctf_trace_class_env_entry_init(entry
);
1700 g_string_assign(entry
->name
, name
);
1703 g_string_assign(entry
->value
.str
, str_value
);
1706 entry
->value
.i
= i_value
;
1710 struct ctf_stream_class
*ctf_trace_class_borrow_stream_class_by_id(
1711 struct ctf_trace_class
*tc
, uint64_t id
)
1714 struct ctf_stream_class
*ret_sc
= NULL
;
1718 for (i
= 0; i
< tc
->stream_classes
->len
; i
++) {
1719 struct ctf_stream_class
*sc
= tc
->stream_classes
->pdata
[i
];
1732 struct ctf_clock_class
*ctf_trace_class_borrow_clock_class_by_name(
1733 struct ctf_trace_class
*tc
, const char *name
)
1736 struct ctf_clock_class
*ret_cc
= NULL
;
1741 for (i
= 0; i
< tc
->clock_classes
->len
; i
++) {
1742 struct ctf_clock_class
*cc
= tc
->clock_classes
->pdata
[i
];
1744 BT_ASSERT(cc
->name
);
1745 if (strcmp(cc
->name
->str
, name
) == 0) {
1756 struct ctf_trace_class_env_entry
*ctf_trace_class_borrow_env_entry_by_index(
1757 struct ctf_trace_class
*tc
, uint64_t index
)
1760 BT_ASSERT(index
< tc
->env_entries
->len
);
1761 return &g_array_index(tc
->env_entries
, struct ctf_trace_class_env_entry
,
1766 struct ctf_trace_class_env_entry
*ctf_trace_class_borrow_env_entry_by_name(
1767 struct ctf_trace_class
*tc
, const char *name
)
1769 struct ctf_trace_class_env_entry
*ret_entry
= NULL
;
1775 for (i
= 0; i
< tc
->env_entries
->len
; i
++) {
1776 struct ctf_trace_class_env_entry
*env_entry
=
1777 ctf_trace_class_borrow_env_entry_by_index(tc
, i
);
1779 if (strcmp(env_entry
->name
->str
, name
) == 0) {
1780 ret_entry
= env_entry
;
1789 #endif /* _CTF_META_H */