ctf: decoding: accommodate LTTng `event-after-packet` timestamp quirk
[babeltrace.git] / src / plugins / ctf / common / metadata / ctf-meta.h
1 #ifndef _CTF_META_H
2 #define _CTF_META_H
3
4 /*
5 * Copyright 2018 - Philippe Proulx <pproulx@efficios.com>
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 */
17
18 #include <babeltrace2/babeltrace.h>
19 #include "common/common.h"
20 #include "common/uuid.h"
21 #include "common/assert.h"
22 #include <glib.h>
23 #include <stdint.h>
24 #include <string.h>
25
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,
35 };
36
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,
50 };
51
52 enum ctf_byte_order {
53 CTF_BYTE_ORDER_UNKNOWN,
54 CTF_BYTE_ORDER_DEFAULT,
55 CTF_BYTE_ORDER_LITTLE,
56 CTF_BYTE_ORDER_BIG,
57 };
58
59 enum ctf_encoding {
60 CTF_ENCODING_NONE,
61 CTF_ENCODING_UTF8,
62 };
63
64 enum ctf_scope {
65 CTF_SCOPE_PACKET_UNKNOWN = -1,
66 CTF_SCOPE_PACKET_HEADER = 0,
67 CTF_SCOPE_PACKET_CONTEXT,
68 CTF_SCOPE_EVENT_HEADER,
69 CTF_SCOPE_EVENT_COMMON_CONTEXT,
70 CTF_SCOPE_EVENT_SPECIFIC_CONTEXT,
71 CTF_SCOPE_EVENT_PAYLOAD,
72 };
73
74 struct ctf_clock_class {
75 GString *name;
76 GString *description;
77 uint64_t frequency;
78 uint64_t precision;
79 int64_t offset_seconds;
80 uint64_t offset_cycles;
81 bt_uuid_t uuid;
82 bool has_uuid;
83 bool is_absolute;
84
85 /* Weak, set during translation */
86 bt_clock_class *ir_cc;
87 };
88
89 struct ctf_field_class {
90 enum ctf_field_class_type type;
91 unsigned int alignment;
92 bool is_compound;
93 bool in_ir;
94
95 /* Weak, set during translation. NULL if `in_ir` is false below. */
96 bt_field_class *ir_fc;
97 };
98
99 struct ctf_field_class_bit_array {
100 struct ctf_field_class base;
101 enum ctf_byte_order byte_order;
102 unsigned int size;
103 };
104
105 struct ctf_field_class_int {
106 struct ctf_field_class_bit_array base;
107 enum ctf_field_class_meaning meaning;
108 bool is_signed;
109 bt_field_class_integer_preferred_display_base disp_base;
110 enum ctf_encoding encoding;
111 int64_t storing_index;
112
113 /* Weak */
114 struct ctf_clock_class *mapped_clock_class;
115 };
116
117 struct ctf_range {
118 union {
119 uint64_t u;
120 int64_t i;
121 } lower;
122
123 union {
124 uint64_t u;
125 int64_t i;
126 } upper;
127 };
128
129 struct ctf_field_class_enum_mapping {
130 GString *label;
131
132 /* Array of `struct ctf_range` */
133 GArray *ranges;
134 };
135
136 struct ctf_field_class_enum {
137 struct ctf_field_class_int base;
138
139 /* Array of `struct ctf_field_class_enum_mapping` */
140 GArray *mappings;
141 };
142
143 struct ctf_field_class_float {
144 struct ctf_field_class_bit_array base;
145 };
146
147 struct ctf_field_class_string {
148 struct ctf_field_class base;
149 enum ctf_encoding encoding;
150 };
151
152 struct ctf_named_field_class {
153 /* Original name which can include a leading `_` */
154 GString *orig_name;
155
156 /* Name as translated to trace IR (leading `_` removed) */
157 GString *name;
158
159 /* Owned by this */
160 struct ctf_field_class *fc;
161 };
162
163 struct ctf_field_class_struct {
164 struct ctf_field_class base;
165
166 /* Array of `struct ctf_named_field_class` */
167 GArray *members;
168 };
169
170 struct ctf_field_path {
171 enum ctf_scope root;
172
173 /* Array of `int64_t` */
174 GArray *path;
175 };
176
177 struct ctf_field_class_variant_range {
178 struct ctf_range range;
179 uint64_t option_index;
180 };
181
182 struct ctf_field_class_variant {
183 struct ctf_field_class base;
184 GString *tag_ref;
185 struct ctf_field_path tag_path;
186 uint64_t stored_tag_index;
187
188 /* Array of `struct ctf_named_field_class` */
189 GArray *options;
190
191 /* Array of `struct ctf_field_class_variant_range` */
192 GArray *ranges;
193
194 /* Weak */
195 struct ctf_field_class_enum *tag_fc;
196 };
197
198 struct ctf_field_class_array_base {
199 struct ctf_field_class base;
200 struct ctf_field_class *elem_fc;
201 bool is_text;
202 };
203
204 struct ctf_field_class_array {
205 struct ctf_field_class_array_base base;
206 enum ctf_field_class_meaning meaning;
207 uint64_t length;
208 };
209
210 struct ctf_field_class_sequence {
211 struct ctf_field_class_array_base base;
212 GString *length_ref;
213 struct ctf_field_path length_path;
214 uint64_t stored_length_index;
215
216 /* Weak */
217 struct ctf_field_class_int *length_fc;
218 };
219
220 struct ctf_event_class {
221 GString *name;
222 uint64_t id;
223 GString *emf_uri;
224 bt_event_class_log_level log_level;
225 bool is_translated;
226 bool is_log_level_set;
227
228 /* Owned by this */
229 struct ctf_field_class *spec_context_fc;
230
231 /* Owned by this */
232 struct ctf_field_class *payload_fc;
233
234 /* Weak, set during translation */
235 bt_event_class *ir_ec;
236 };
237
238 struct ctf_stream_class {
239 uint64_t id;
240 bool is_translated;
241 bool packets_have_ts_begin;
242 bool packets_have_ts_end;
243 bool has_discarded_events;
244 bool has_discarded_packets;
245 bool discarded_events_have_default_cs;
246 bool discarded_packets_have_default_cs;
247
248 /* Owned by this */
249 struct ctf_field_class *packet_context_fc;
250
251 /* Owned by this */
252 struct ctf_field_class *event_header_fc;
253
254 /* Owned by this */
255 struct ctf_field_class *event_common_context_fc;
256
257 /* Array of `struct ctf_event_class *`, owned by this */
258 GPtrArray *event_classes;
259
260 /*
261 * Hash table mapping event class IDs to `struct ctf_event_class *`,
262 * weak.
263 */
264 GHashTable *event_classes_by_id;
265
266 /* Weak */
267 struct ctf_clock_class *default_clock_class;
268
269 /* Weak, set during translation */
270 bt_stream_class *ir_sc;
271 };
272
273 enum ctf_trace_class_env_entry_type {
274 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
275 CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
276 };
277
278 struct ctf_trace_class_env_entry {
279 enum ctf_trace_class_env_entry_type type;
280 GString *name;
281
282 struct {
283 int64_t i;
284 GString *str;
285 } value;
286 };
287
288 struct ctf_trace_class {
289 unsigned int major;
290 unsigned int minor;
291 bt_uuid_t uuid;
292 bool is_uuid_set;
293 enum ctf_byte_order default_byte_order;
294
295 /* Owned by this */
296 struct ctf_field_class *packet_header_fc;
297
298 uint64_t stored_value_count;
299
300 /* Array of `struct ctf_clock_class *` (owned by this) */
301 GPtrArray *clock_classes;
302
303 /* Array of `struct ctf_stream_class *` */
304 GPtrArray *stream_classes;
305
306 /* Array of `struct ctf_trace_class_env_entry` */
307 GArray *env_entries;
308
309 bool is_translated;
310
311 /* Weak, set during translation */
312 bt_trace_class *ir_tc;
313
314 struct {
315 bool lttng_crash;
316 bool lttng_event_after_packet;
317 } quirks;
318 };
319
320 static inline
321 void ctf_field_class_destroy(struct ctf_field_class *fc);
322
323 static inline
324 void _ctf_field_class_init(struct ctf_field_class *fc,
325 enum ctf_field_class_type type, unsigned int alignment)
326 {
327 BT_ASSERT(fc);
328 fc->type = type;
329 fc->alignment = alignment;
330 fc->in_ir = false;
331 }
332
333 static inline
334 void _ctf_field_class_bit_array_init(struct ctf_field_class_bit_array *fc,
335 enum ctf_field_class_type type)
336 {
337 _ctf_field_class_init((void *) fc, type, 1);
338 }
339
340 static inline
341 void _ctf_field_class_int_init(struct ctf_field_class_int *fc,
342 enum ctf_field_class_type type)
343 {
344 _ctf_field_class_bit_array_init((void *) fc, type);
345 fc->meaning = CTF_FIELD_CLASS_MEANING_NONE;
346 fc->storing_index = -1;
347 }
348
349 static inline
350 void ctf_field_path_init(struct ctf_field_path *field_path)
351 {
352 BT_ASSERT(field_path);
353 field_path->path = g_array_new(FALSE, TRUE, sizeof(int64_t));
354 BT_ASSERT(field_path->path);
355 }
356
357 static inline
358 void ctf_field_path_fini(struct ctf_field_path *field_path)
359 {
360 BT_ASSERT(field_path);
361
362 if (field_path->path) {
363 g_array_free(field_path->path, TRUE);
364 }
365 }
366
367 static inline
368 void _ctf_named_field_class_init(struct ctf_named_field_class *named_fc)
369 {
370 BT_ASSERT(named_fc);
371 named_fc->name = g_string_new(NULL);
372 BT_ASSERT(named_fc->name);
373 named_fc->orig_name = g_string_new(NULL);
374 BT_ASSERT(named_fc->orig_name);
375 }
376
377 static inline
378 void _ctf_named_field_class_fini(struct ctf_named_field_class *named_fc)
379 {
380 BT_ASSERT(named_fc);
381
382 if (named_fc->name) {
383 g_string_free(named_fc->name, TRUE);
384 }
385
386 if (named_fc->orig_name) {
387 g_string_free(named_fc->orig_name, TRUE);
388 }
389
390 ctf_field_class_destroy(named_fc->fc);
391 }
392
393 static inline
394 void _ctf_field_class_enum_mapping_init(
395 struct ctf_field_class_enum_mapping *mapping)
396 {
397 BT_ASSERT(mapping);
398 mapping->label = g_string_new(NULL);
399 BT_ASSERT(mapping->label);
400 mapping->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_range));
401 BT_ASSERT(mapping->ranges);
402 }
403
404 static inline
405 void _ctf_field_class_enum_mapping_fini(
406 struct ctf_field_class_enum_mapping *mapping)
407 {
408 BT_ASSERT(mapping);
409
410 if (mapping->label) {
411 g_string_free(mapping->label, TRUE);
412 }
413
414 if (mapping->ranges) {
415 g_array_free(mapping->ranges, TRUE);
416 }
417 }
418
419 static inline
420 struct ctf_field_class_int *ctf_field_class_int_create(void)
421 {
422 struct ctf_field_class_int *fc = g_new0(struct ctf_field_class_int, 1);
423
424 BT_ASSERT(fc);
425 _ctf_field_class_int_init(fc, CTF_FIELD_CLASS_TYPE_INT);
426 return fc;
427 }
428
429 static inline
430 struct ctf_field_class_float *ctf_field_class_float_create(void)
431 {
432 struct ctf_field_class_float *fc =
433 g_new0(struct ctf_field_class_float, 1);
434
435 BT_ASSERT(fc);
436 _ctf_field_class_bit_array_init((void *) fc, CTF_FIELD_CLASS_TYPE_FLOAT);
437 return fc;
438 }
439
440 static inline
441 struct ctf_field_class_string *ctf_field_class_string_create(void)
442 {
443 struct ctf_field_class_string *fc =
444 g_new0(struct ctf_field_class_string, 1);
445
446 BT_ASSERT(fc);
447 _ctf_field_class_init((void *) fc, CTF_FIELD_CLASS_TYPE_STRING, 8);
448 return fc;
449 }
450
451 static inline
452 struct ctf_field_class_enum *ctf_field_class_enum_create(void)
453 {
454 struct ctf_field_class_enum *fc = g_new0(struct ctf_field_class_enum, 1);
455
456 BT_ASSERT(fc);
457 _ctf_field_class_int_init((void *) fc, CTF_FIELD_CLASS_TYPE_ENUM);
458 fc->mappings = g_array_new(FALSE, TRUE,
459 sizeof(struct ctf_field_class_enum_mapping));
460 BT_ASSERT(fc->mappings);
461 return fc;
462 }
463
464 static inline
465 struct ctf_field_class_struct *ctf_field_class_struct_create(void)
466 {
467 struct ctf_field_class_struct *fc =
468 g_new0(struct ctf_field_class_struct, 1);
469
470 BT_ASSERT(fc);
471 _ctf_field_class_init((void *) fc, CTF_FIELD_CLASS_TYPE_STRUCT, 1);
472 fc->members = g_array_new(FALSE, TRUE,
473 sizeof(struct ctf_named_field_class));
474 BT_ASSERT(fc->members);
475 fc->base.is_compound = true;
476 return fc;
477 }
478
479 static inline
480 struct ctf_field_class_variant *ctf_field_class_variant_create(void)
481 {
482 struct ctf_field_class_variant *fc =
483 g_new0(struct ctf_field_class_variant, 1);
484
485 BT_ASSERT(fc);
486 _ctf_field_class_init((void *) fc, CTF_FIELD_CLASS_TYPE_VARIANT, 1);
487 fc->options = g_array_new(FALSE, TRUE,
488 sizeof(struct ctf_named_field_class));
489 BT_ASSERT(fc->options);
490 fc->ranges = g_array_new(FALSE, TRUE,
491 sizeof(struct ctf_field_class_variant_range));
492 BT_ASSERT(fc->ranges);
493 fc->tag_ref = g_string_new(NULL);
494 BT_ASSERT(fc->tag_ref);
495 ctf_field_path_init(&fc->tag_path);
496 fc->base.is_compound = true;
497 return fc;
498 }
499
500 static inline
501 struct ctf_field_class_array *ctf_field_class_array_create(void)
502 {
503 struct ctf_field_class_array *fc =
504 g_new0(struct ctf_field_class_array, 1);
505
506 BT_ASSERT(fc);
507 _ctf_field_class_init((void *) fc, CTF_FIELD_CLASS_TYPE_ARRAY, 1);
508 fc->base.base.is_compound = true;
509 return fc;
510 }
511
512 static inline
513 struct ctf_field_class_sequence *ctf_field_class_sequence_create(void)
514 {
515 struct ctf_field_class_sequence *fc =
516 g_new0(struct ctf_field_class_sequence, 1);
517
518 BT_ASSERT(fc);
519 _ctf_field_class_init((void *) fc, CTF_FIELD_CLASS_TYPE_SEQUENCE, 1);
520 fc->length_ref = g_string_new(NULL);
521 BT_ASSERT(fc->length_ref);
522 ctf_field_path_init(&fc->length_path);
523 fc->base.base.is_compound = true;
524 return fc;
525 }
526
527 static inline
528 void _ctf_field_class_int_destroy(struct ctf_field_class_int *fc)
529 {
530 BT_ASSERT(fc);
531 g_free(fc);
532 }
533
534 static inline
535 void _ctf_field_class_enum_destroy(struct ctf_field_class_enum *fc)
536 {
537 BT_ASSERT(fc);
538
539 if (fc->mappings) {
540 uint64_t i;
541
542 for (i = 0; i < fc->mappings->len; i++) {
543 struct ctf_field_class_enum_mapping *mapping =
544 &g_array_index(fc->mappings,
545 struct ctf_field_class_enum_mapping, i);
546
547 _ctf_field_class_enum_mapping_fini(mapping);
548 }
549
550 g_array_free(fc->mappings, TRUE);
551 }
552
553 g_free(fc);
554 }
555
556 static inline
557 void _ctf_field_class_float_destroy(struct ctf_field_class_float *fc)
558 {
559 BT_ASSERT(fc);
560 g_free(fc);
561 }
562
563 static inline
564 void _ctf_field_class_string_destroy(struct ctf_field_class_string *fc)
565 {
566 BT_ASSERT(fc);
567 g_free(fc);
568 }
569
570 static inline
571 void _ctf_field_class_struct_destroy(struct ctf_field_class_struct *fc)
572 {
573 BT_ASSERT(fc);
574
575 if (fc->members) {
576 uint64_t i;
577
578 for (i = 0; i < fc->members->len; i++) {
579 struct ctf_named_field_class *named_fc =
580 &g_array_index(fc->members,
581 struct ctf_named_field_class, i);
582
583 _ctf_named_field_class_fini(named_fc);
584 }
585
586 g_array_free(fc->members, TRUE);
587 }
588
589 g_free(fc);
590 }
591
592 static inline
593 void _ctf_field_class_array_base_fini(struct ctf_field_class_array_base *fc)
594 {
595 BT_ASSERT(fc);
596 ctf_field_class_destroy(fc->elem_fc);
597 }
598
599 static inline
600 void _ctf_field_class_array_destroy(struct ctf_field_class_array *fc)
601 {
602 BT_ASSERT(fc);
603 _ctf_field_class_array_base_fini((void *) fc);
604 g_free(fc);
605 }
606
607 static inline
608 void _ctf_field_class_sequence_destroy(struct ctf_field_class_sequence *fc)
609 {
610 BT_ASSERT(fc);
611 _ctf_field_class_array_base_fini((void *) fc);
612
613 if (fc->length_ref) {
614 g_string_free(fc->length_ref, TRUE);
615 }
616
617 ctf_field_path_fini(&fc->length_path);
618 g_free(fc);
619 }
620
621 static inline
622 void _ctf_field_class_variant_destroy(struct ctf_field_class_variant *fc)
623 {
624 BT_ASSERT(fc);
625
626 if (fc->options) {
627 uint64_t i;
628
629 for (i = 0; i < fc->options->len; i++) {
630 struct ctf_named_field_class *named_fc =
631 &g_array_index(fc->options,
632 struct ctf_named_field_class, i);
633
634 _ctf_named_field_class_fini(named_fc);
635 }
636
637 g_array_free(fc->options, TRUE);
638 }
639
640 if (fc->ranges) {
641 g_array_free(fc->ranges, TRUE);
642 }
643
644 if (fc->tag_ref) {
645 g_string_free(fc->tag_ref, TRUE);
646 }
647
648 ctf_field_path_fini(&fc->tag_path);
649 g_free(fc);
650 }
651
652 static inline
653 void ctf_field_class_destroy(struct ctf_field_class *fc)
654 {
655 if (!fc) {
656 return;
657 }
658
659 switch (fc->type) {
660 case CTF_FIELD_CLASS_TYPE_INT:
661 _ctf_field_class_int_destroy((void *) fc);
662 break;
663 case CTF_FIELD_CLASS_TYPE_ENUM:
664 _ctf_field_class_enum_destroy((void *) fc);
665 break;
666 case CTF_FIELD_CLASS_TYPE_FLOAT:
667 _ctf_field_class_float_destroy((void *) fc);
668 break;
669 case CTF_FIELD_CLASS_TYPE_STRING:
670 _ctf_field_class_string_destroy((void *) fc);
671 break;
672 case CTF_FIELD_CLASS_TYPE_STRUCT:
673 _ctf_field_class_struct_destroy((void *) fc);
674 break;
675 case CTF_FIELD_CLASS_TYPE_ARRAY:
676 _ctf_field_class_array_destroy((void *) fc);
677 break;
678 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
679 _ctf_field_class_sequence_destroy((void *) fc);
680 break;
681 case CTF_FIELD_CLASS_TYPE_VARIANT:
682 _ctf_field_class_variant_destroy((void *) fc);
683 break;
684 default:
685 abort();
686 }
687 }
688
689 static inline
690 struct ctf_range *ctf_field_class_enum_mapping_borrow_range_by_index(
691 struct ctf_field_class_enum_mapping *mapping, uint64_t index)
692 {
693 BT_ASSERT(mapping);
694 BT_ASSERT(index < mapping->ranges->len);
695 return &g_array_index(mapping->ranges, struct ctf_range, index);
696 }
697
698 static inline
699 struct ctf_field_class_enum_mapping *ctf_field_class_enum_borrow_mapping_by_index(
700 struct ctf_field_class_enum *fc, uint64_t index)
701 {
702 BT_ASSERT(fc);
703 BT_ASSERT(index < fc->mappings->len);
704 return &g_array_index(fc->mappings, struct ctf_field_class_enum_mapping,
705 index);
706 }
707
708 static inline
709 struct ctf_field_class_enum_mapping *ctf_field_class_enum_borrow_mapping_by_label(
710 struct ctf_field_class_enum *fc, const char *label)
711 {
712 struct ctf_field_class_enum_mapping *ret_mapping = NULL;
713 uint64_t i;
714
715 BT_ASSERT(fc);
716 BT_ASSERT(label);
717
718 for (i = 0; i < fc->mappings->len; i++) {
719 struct ctf_field_class_enum_mapping *mapping =
720 ctf_field_class_enum_borrow_mapping_by_index(fc, i);
721
722 if (strcmp(mapping->label->str, label) == 0) {
723 ret_mapping = mapping;
724 goto end;
725 }
726 }
727
728 end:
729 return ret_mapping;
730 }
731
732 static inline
733 void ctf_field_class_enum_map_range(struct ctf_field_class_enum *fc,
734 const char *label, uint64_t u_lower, uint64_t u_upper)
735 {
736 struct ctf_field_class_enum_mapping *mapping = NULL;
737 struct ctf_range range = {
738 .lower.u = u_lower,
739 .upper.u = u_upper,
740 };
741 uint64_t i;
742
743 BT_ASSERT(fc);
744 BT_ASSERT(label);
745
746 for (i = 0; i < fc->mappings->len; i++) {
747 mapping = ctf_field_class_enum_borrow_mapping_by_index(
748 fc, i);
749
750 if (strcmp(mapping->label->str, label) == 0) {
751 break;
752 }
753 }
754
755 if (i == fc->mappings->len) {
756 mapping = NULL;
757 }
758
759 if (!mapping) {
760 g_array_set_size(fc->mappings, fc->mappings->len + 1);
761 mapping = ctf_field_class_enum_borrow_mapping_by_index(
762 fc, fc->mappings->len - 1);
763 _ctf_field_class_enum_mapping_init(mapping);
764 g_string_assign(mapping->label, label);
765 }
766
767 g_array_append_val(mapping->ranges, range);
768 }
769
770 static inline
771 struct ctf_named_field_class *ctf_field_class_struct_borrow_member_by_index(
772 struct ctf_field_class_struct *fc, uint64_t index)
773 {
774 BT_ASSERT(fc);
775 BT_ASSERT(index < fc->members->len);
776 return &g_array_index(fc->members, struct ctf_named_field_class,
777 index);
778 }
779
780 static inline
781 struct ctf_named_field_class *ctf_field_class_struct_borrow_member_by_name(
782 struct ctf_field_class_struct *fc, const char *name)
783 {
784 uint64_t i;
785 struct ctf_named_field_class *ret_named_fc = NULL;
786
787 BT_ASSERT(fc);
788 BT_ASSERT(name);
789
790 for (i = 0; i < fc->members->len; i++) {
791 struct ctf_named_field_class *named_fc =
792 ctf_field_class_struct_borrow_member_by_index(fc, i);
793
794 if (strcmp(name, named_fc->name->str) == 0) {
795 ret_named_fc = named_fc;
796 goto end;
797 }
798 }
799
800 end:
801 return ret_named_fc;
802 }
803
804 static inline
805 struct ctf_field_class *ctf_field_class_struct_borrow_member_field_class_by_name(
806 struct ctf_field_class_struct *struct_fc, const char *name)
807 {
808 struct ctf_named_field_class *named_fc = NULL;
809 struct ctf_field_class *fc = NULL;
810
811 if (!struct_fc) {
812 goto end;
813 }
814
815 named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name);
816 if (!named_fc) {
817 goto end;
818 }
819
820 fc = named_fc->fc;
821
822 end:
823 return fc;
824 }
825
826 static inline
827 struct ctf_field_class_int *
828 ctf_field_class_struct_borrow_member_int_field_class_by_name(
829 struct ctf_field_class_struct *struct_fc, const char *name)
830 {
831 struct ctf_field_class_int *int_fc = NULL;
832
833 int_fc = (void *)
834 ctf_field_class_struct_borrow_member_field_class_by_name(
835 struct_fc, name);
836 if (!int_fc) {
837 goto end;
838 }
839
840 if (int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_INT &&
841 int_fc->base.base.type != CTF_FIELD_CLASS_TYPE_ENUM) {
842 int_fc = NULL;
843 goto end;
844 }
845
846 end:
847 return int_fc;
848 }
849
850 static inline
851 void _ctf_named_field_class_unescape_orig_name(
852 struct ctf_named_field_class *named_fc)
853 {
854 const char *name = named_fc->orig_name->str;
855
856 if (name[0] == '_') {
857 name++;
858 }
859
860 g_string_assign(named_fc->name, name);
861 }
862
863 static inline
864 void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc,
865 const char *orig_name, struct ctf_field_class *member_fc)
866 {
867 struct ctf_named_field_class *named_fc;
868
869 BT_ASSERT(fc);
870 BT_ASSERT(orig_name);
871 g_array_set_size(fc->members, fc->members->len + 1);
872
873 named_fc = &g_array_index(fc->members, struct ctf_named_field_class,
874 fc->members->len - 1);
875 _ctf_named_field_class_init(named_fc);
876 g_string_assign(named_fc->orig_name, orig_name);
877 _ctf_named_field_class_unescape_orig_name(named_fc);
878 named_fc->fc = member_fc;
879
880 if (member_fc->alignment > fc->base.alignment) {
881 fc->base.alignment = member_fc->alignment;
882 }
883 }
884
885 static inline
886 struct ctf_named_field_class *ctf_field_class_variant_borrow_option_by_index(
887 struct ctf_field_class_variant *fc, uint64_t index)
888 {
889 BT_ASSERT(fc);
890 BT_ASSERT(index < fc->options->len);
891 return &g_array_index(fc->options, struct ctf_named_field_class,
892 index);
893 }
894
895 static inline
896 struct ctf_named_field_class *ctf_field_class_variant_borrow_option_by_name(
897 struct ctf_field_class_variant *fc, const char *name)
898 {
899 uint64_t i;
900 struct ctf_named_field_class *ret_named_fc = NULL;
901
902 BT_ASSERT(fc);
903 BT_ASSERT(name);
904
905 for (i = 0; i < fc->options->len; i++) {
906 struct ctf_named_field_class *named_fc =
907 ctf_field_class_variant_borrow_option_by_index(fc, i);
908
909 if (strcmp(name, named_fc->name->str) == 0) {
910 ret_named_fc = named_fc;
911 goto end;
912 }
913 }
914
915 end:
916 return ret_named_fc;
917 }
918
919 static inline
920 struct ctf_field_class_variant_range *
921 ctf_field_class_variant_borrow_range_by_index(
922 struct ctf_field_class_variant *fc, uint64_t index)
923 {
924 BT_ASSERT(fc);
925 BT_ASSERT(index < fc->ranges->len);
926 return &g_array_index(fc->ranges, struct ctf_field_class_variant_range,
927 index);
928 }
929
930 static inline
931 void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc,
932 const char *orig_name, struct ctf_field_class *option_fc)
933 {
934 struct ctf_named_field_class *named_fc;
935
936 BT_ASSERT(fc);
937 BT_ASSERT(orig_name);
938 g_array_set_size(fc->options, fc->options->len + 1);
939
940 named_fc = &g_array_index(fc->options, struct ctf_named_field_class,
941 fc->options->len - 1);
942 _ctf_named_field_class_init(named_fc);
943 g_string_assign(named_fc->orig_name, orig_name);
944 _ctf_named_field_class_unescape_orig_name(named_fc);
945 named_fc->fc = option_fc;
946 }
947
948 static inline
949 void ctf_field_class_variant_set_tag_field_class(
950 struct ctf_field_class_variant *fc,
951 struct ctf_field_class_enum *tag_fc)
952 {
953 uint64_t option_i;
954
955 BT_ASSERT(fc);
956 BT_ASSERT(tag_fc);
957 fc->tag_fc = tag_fc;
958
959 for (option_i = 0; option_i < fc->options->len; option_i++) {
960 uint64_t range_i;
961 struct ctf_named_field_class *named_fc =
962 ctf_field_class_variant_borrow_option_by_index(
963 fc, option_i);
964 struct ctf_field_class_enum_mapping *mapping;
965
966 mapping = ctf_field_class_enum_borrow_mapping_by_label(
967 tag_fc, named_fc->orig_name->str);
968 if (!mapping) {
969 continue;
970 }
971
972 for (range_i = 0; range_i < mapping->ranges->len;
973 range_i++) {
974 struct ctf_range *range =
975 ctf_field_class_enum_mapping_borrow_range_by_index(
976 mapping, range_i);
977 struct ctf_field_class_variant_range var_range;
978
979 var_range.range = *range;
980 var_range.option_index = option_i;
981 g_array_append_val(fc->ranges, var_range);
982 }
983 }
984 }
985
986 static inline
987 struct ctf_field_class *ctf_field_class_compound_borrow_field_class_by_index(
988 struct ctf_field_class *comp_fc, uint64_t index)
989 {
990 struct ctf_field_class *fc = NULL;
991
992 switch (comp_fc->type) {
993 case CTF_FIELD_CLASS_TYPE_STRUCT:
994 {
995 struct ctf_named_field_class *named_fc =
996 ctf_field_class_struct_borrow_member_by_index(
997 (void *) comp_fc, index);
998
999 BT_ASSERT(named_fc);
1000 fc = named_fc->fc;
1001 break;
1002 }
1003 case CTF_FIELD_CLASS_TYPE_VARIANT:
1004 {
1005 struct ctf_named_field_class *named_fc =
1006 ctf_field_class_variant_borrow_option_by_index(
1007 (void *) comp_fc, index);
1008
1009 BT_ASSERT(named_fc);
1010 fc = named_fc->fc;
1011 break;
1012 }
1013 case CTF_FIELD_CLASS_TYPE_ARRAY:
1014 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1015 {
1016 struct ctf_field_class_array_base *array_fc = (void *) comp_fc;
1017
1018 fc = array_fc->elem_fc;
1019 break;
1020 }
1021 default:
1022 break;
1023 }
1024
1025 return fc;
1026 }
1027
1028 static inline
1029 uint64_t ctf_field_class_compound_get_field_class_count(struct ctf_field_class *fc)
1030 {
1031 uint64_t field_count;
1032
1033 switch (fc->type) {
1034 case CTF_FIELD_CLASS_TYPE_STRUCT:
1035 {
1036 struct ctf_field_class_struct *struct_fc = (void *) fc;
1037
1038 field_count = struct_fc->members->len;
1039 break;
1040 }
1041 case CTF_FIELD_CLASS_TYPE_VARIANT:
1042 {
1043 struct ctf_field_class_variant *var_fc = (void *) fc;
1044
1045 field_count = var_fc->options->len;
1046 break;
1047 }
1048 case CTF_FIELD_CLASS_TYPE_ARRAY:
1049 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1050 /*
1051 * Array and sequence types always contain a single
1052 * member (the element type).
1053 */
1054 field_count = 1;
1055 break;
1056 default:
1057 abort();
1058 }
1059
1060 return field_count;
1061 }
1062
1063 static inline
1064 int64_t ctf_field_class_compound_get_field_class_index_from_orig_name(
1065 struct ctf_field_class *fc, const char *orig_name)
1066 {
1067 int64_t ret_index = -1;
1068 uint64_t i;
1069
1070 switch (fc->type) {
1071 case CTF_FIELD_CLASS_TYPE_STRUCT:
1072 {
1073 struct ctf_field_class_struct *struct_fc = (void *) fc;
1074
1075 for (i = 0; i < struct_fc->members->len; i++) {
1076 struct ctf_named_field_class *named_fc =
1077 ctf_field_class_struct_borrow_member_by_index(
1078 struct_fc, i);
1079
1080 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1081 ret_index = (int64_t) i;
1082 goto end;
1083 }
1084 }
1085
1086 break;
1087 }
1088 case CTF_FIELD_CLASS_TYPE_VARIANT:
1089 {
1090 struct ctf_field_class_variant *var_fc = (void *) fc;
1091
1092 for (i = 0; i < var_fc->options->len; i++) {
1093 struct ctf_named_field_class *named_fc =
1094 ctf_field_class_variant_borrow_option_by_index(
1095 var_fc, i);
1096
1097 if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
1098 ret_index = (int64_t) i;
1099 goto end;
1100 }
1101 }
1102
1103 break;
1104 }
1105 default:
1106 break;
1107 }
1108
1109 end:
1110 return ret_index;
1111 }
1112
1113 static inline
1114 void ctf_field_path_append_index(struct ctf_field_path *fp, int64_t index)
1115 {
1116 BT_ASSERT(fp);
1117 g_array_append_val(fp->path, index);
1118 }
1119
1120 static inline
1121 int64_t ctf_field_path_borrow_index_by_index(struct ctf_field_path *fp,
1122 uint64_t index)
1123 {
1124 BT_ASSERT(fp);
1125 BT_ASSERT(index < fp->path->len);
1126 return g_array_index(fp->path, int64_t, index);
1127 }
1128
1129 static inline
1130 void ctf_field_path_clear(struct ctf_field_path *fp)
1131 {
1132 BT_ASSERT(fp);
1133 g_array_set_size(fp->path, 0);
1134 }
1135
1136 static inline
1137 const char *ctf_scope_string(enum ctf_scope scope)
1138 {
1139 switch (scope) {
1140 case CTF_SCOPE_PACKET_HEADER:
1141 return "PACKET_HEADER";
1142 case CTF_SCOPE_PACKET_CONTEXT:
1143 return "PACKET_CONTEXT";
1144 case CTF_SCOPE_EVENT_HEADER:
1145 return "EVENT_HEADER";
1146 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1147 return "EVENT_COMMON_CONTEXT";
1148 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1149 return "EVENT_SPECIFIC_CONTEXT";
1150 case CTF_SCOPE_EVENT_PAYLOAD:
1151 return "EVENT_PAYLOAD";
1152 default:
1153 abort();
1154 }
1155 }
1156
1157 static inline
1158 GString *ctf_field_path_string(struct ctf_field_path *path)
1159 {
1160 GString *str = g_string_new(NULL);
1161 uint64_t i;
1162
1163 BT_ASSERT(path);
1164
1165 if (!str) {
1166 goto end;
1167 }
1168
1169 g_string_append_printf(str, "[%s", ctf_scope_string(path->root));
1170
1171 for (i = 0; i < path->path->len; i++) {
1172 g_string_append_printf(str, ", %" PRId64,
1173 ctf_field_path_borrow_index_by_index(path, i));
1174 }
1175
1176 g_string_append(str, "]");
1177
1178 end:
1179 return str;
1180 }
1181
1182 static inline
1183 struct ctf_field_class *ctf_field_path_borrow_field_class(
1184 struct ctf_field_path *field_path,
1185 struct ctf_trace_class *tc,
1186 struct ctf_stream_class *sc,
1187 struct ctf_event_class *ec)
1188 {
1189 uint64_t i;
1190 struct ctf_field_class *fc;
1191
1192 switch (field_path->root) {
1193 case CTF_SCOPE_PACKET_HEADER:
1194 fc = tc->packet_header_fc;
1195 break;
1196 case CTF_SCOPE_PACKET_CONTEXT:
1197 fc = sc->packet_context_fc;
1198 break;
1199 case CTF_SCOPE_EVENT_HEADER:
1200 fc = sc->event_header_fc;
1201 break;
1202 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
1203 fc = sc->event_common_context_fc;
1204 break;
1205 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
1206 fc = ec->spec_context_fc;
1207 break;
1208 case CTF_SCOPE_EVENT_PAYLOAD:
1209 fc = ec->payload_fc;
1210 break;
1211 default:
1212 abort();
1213 }
1214
1215 BT_ASSERT(fc);
1216
1217 for (i = 0; i < field_path->path->len; i++) {
1218 int64_t child_index =
1219 ctf_field_path_borrow_index_by_index(field_path, i);
1220 struct ctf_field_class *child_fc =
1221 ctf_field_class_compound_borrow_field_class_by_index(
1222 fc, child_index);
1223 BT_ASSERT(child_fc);
1224 fc = child_fc;
1225 }
1226
1227 BT_ASSERT(fc);
1228 return fc;
1229 }
1230
1231 static inline
1232 struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc);
1233
1234 static inline
1235 void ctf_field_class_bit_array_copy_content(
1236 struct ctf_field_class_bit_array *dst_fc,
1237 struct ctf_field_class_bit_array *src_fc)
1238 {
1239 BT_ASSERT(dst_fc);
1240 BT_ASSERT(src_fc);
1241 dst_fc->byte_order = src_fc->byte_order;
1242 dst_fc->size = src_fc->size;
1243 }
1244
1245 static inline
1246 void ctf_field_class_int_copy_content(
1247 struct ctf_field_class_int *dst_fc,
1248 struct ctf_field_class_int *src_fc)
1249 {
1250 ctf_field_class_bit_array_copy_content((void *) dst_fc, (void *) src_fc);
1251 dst_fc->meaning = src_fc->meaning;
1252 dst_fc->is_signed = src_fc->is_signed;
1253 dst_fc->disp_base = src_fc->disp_base;
1254 dst_fc->encoding = src_fc->encoding;
1255 dst_fc->mapped_clock_class = src_fc->mapped_clock_class;
1256 dst_fc->storing_index = src_fc->storing_index;
1257 }
1258
1259 static inline
1260 struct ctf_field_class_int *_ctf_field_class_int_copy(
1261 struct ctf_field_class_int *fc)
1262 {
1263 struct ctf_field_class_int *copy_fc = ctf_field_class_int_create();
1264
1265 BT_ASSERT(copy_fc);
1266 ctf_field_class_int_copy_content(copy_fc, fc);
1267 return copy_fc;
1268 }
1269
1270 static inline
1271 struct ctf_field_class_enum *_ctf_field_class_enum_copy(
1272 struct ctf_field_class_enum *fc)
1273 {
1274 struct ctf_field_class_enum *copy_fc = ctf_field_class_enum_create();
1275 uint64_t i;
1276
1277 BT_ASSERT(copy_fc);
1278 ctf_field_class_int_copy_content((void *) copy_fc, (void *) fc);
1279
1280 for (i = 0; i < fc->mappings->len; i++) {
1281 uint64_t range_i;
1282
1283 struct ctf_field_class_enum_mapping *mapping =
1284 &g_array_index(fc->mappings,
1285 struct ctf_field_class_enum_mapping, i);
1286
1287 for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
1288 struct ctf_range *range =
1289 &g_array_index(mapping->ranges,
1290 struct ctf_range, range_i);
1291
1292 ctf_field_class_enum_map_range(copy_fc,
1293 mapping->label->str, range->lower.u,
1294 range->upper.u);
1295 }
1296 }
1297
1298 return copy_fc;
1299 }
1300
1301 static inline
1302 struct ctf_field_class_float *_ctf_field_class_float_copy(
1303 struct ctf_field_class_float *fc)
1304 {
1305 struct ctf_field_class_float *copy_fc = ctf_field_class_float_create();
1306
1307 BT_ASSERT(copy_fc);
1308 ctf_field_class_bit_array_copy_content((void *) copy_fc, (void *) fc);
1309 return copy_fc;
1310 }
1311
1312 static inline
1313 struct ctf_field_class_string *_ctf_field_class_string_copy(
1314 struct ctf_field_class_string *fc)
1315 {
1316 struct ctf_field_class_string *copy_fc = ctf_field_class_string_create();
1317
1318 BT_ASSERT(copy_fc);
1319 return copy_fc;
1320 }
1321
1322 static inline
1323 struct ctf_field_class_struct *_ctf_field_class_struct_copy(
1324 struct ctf_field_class_struct *fc)
1325 {
1326 struct ctf_field_class_struct *copy_fc = ctf_field_class_struct_create();
1327 uint64_t i;
1328
1329 BT_ASSERT(copy_fc);
1330
1331 for (i = 0; i < fc->members->len; i++) {
1332 struct ctf_named_field_class *named_fc =
1333 &g_array_index(fc->members,
1334 struct ctf_named_field_class, i);
1335
1336 ctf_field_class_struct_append_member(copy_fc,
1337 named_fc->name->str,
1338 ctf_field_class_copy(named_fc->fc));
1339 }
1340
1341 return copy_fc;
1342 }
1343
1344 static inline
1345 void ctf_field_path_copy_content(struct ctf_field_path *dst_fp,
1346 struct ctf_field_path *src_fp)
1347 {
1348 uint64_t i;
1349
1350 BT_ASSERT(dst_fp);
1351 BT_ASSERT(src_fp);
1352 dst_fp->root = src_fp->root;
1353 ctf_field_path_clear(dst_fp);
1354
1355 for (i = 0; i < src_fp->path->len; i++) {
1356 int64_t index = ctf_field_path_borrow_index_by_index(
1357 src_fp, i);
1358
1359 ctf_field_path_append_index(dst_fp, index);
1360 }
1361 }
1362
1363 static inline
1364 struct ctf_field_class_variant *_ctf_field_class_variant_copy(
1365 struct ctf_field_class_variant *fc)
1366 {
1367 struct ctf_field_class_variant *copy_fc =
1368 ctf_field_class_variant_create();
1369 uint64_t i;
1370
1371 BT_ASSERT(copy_fc);
1372
1373 for (i = 0; i < fc->options->len; i++) {
1374 struct ctf_named_field_class *named_fc =
1375 &g_array_index(fc->options,
1376 struct ctf_named_field_class, i);
1377
1378 ctf_field_class_variant_append_option(copy_fc,
1379 named_fc->name->str,
1380 ctf_field_class_copy(named_fc->fc));
1381 }
1382
1383 for (i = 0; i < fc->ranges->len; i++) {
1384 struct ctf_field_class_variant_range *range =
1385 &g_array_index(fc->ranges,
1386 struct ctf_field_class_variant_range, i);
1387
1388 g_array_append_val(copy_fc->ranges, *range);
1389 }
1390
1391 ctf_field_path_copy_content(&copy_fc->tag_path, &fc->tag_path);
1392 g_string_assign(copy_fc->tag_ref, fc->tag_ref->str);
1393 copy_fc->stored_tag_index = fc->stored_tag_index;
1394 return copy_fc;
1395 }
1396
1397 static inline
1398 void ctf_field_class_array_base_copy_content(
1399 struct ctf_field_class_array_base *dst_fc,
1400 struct ctf_field_class_array_base *src_fc)
1401 {
1402 BT_ASSERT(dst_fc);
1403 BT_ASSERT(src_fc);
1404 dst_fc->elem_fc = ctf_field_class_copy(src_fc->elem_fc);
1405 dst_fc->is_text = src_fc->is_text;
1406 }
1407
1408 static inline
1409 struct ctf_field_class_array *_ctf_field_class_array_copy(
1410 struct ctf_field_class_array *fc)
1411 {
1412 struct ctf_field_class_array *copy_fc = ctf_field_class_array_create();
1413
1414 BT_ASSERT(copy_fc);
1415 ctf_field_class_array_base_copy_content((void *) copy_fc, (void *) fc);
1416 copy_fc->length = fc->length;
1417 return copy_fc;
1418 }
1419
1420 static inline
1421 struct ctf_field_class_sequence *_ctf_field_class_sequence_copy(
1422 struct ctf_field_class_sequence *fc)
1423 {
1424 struct ctf_field_class_sequence *copy_fc =
1425 ctf_field_class_sequence_create();
1426
1427 BT_ASSERT(copy_fc);
1428 ctf_field_class_array_base_copy_content((void *) copy_fc, (void *) fc);
1429 ctf_field_path_copy_content(&copy_fc->length_path, &fc->length_path);
1430 g_string_assign(copy_fc->length_ref, fc->length_ref->str);
1431 copy_fc->stored_length_index = fc->stored_length_index;
1432 return copy_fc;
1433 }
1434
1435 static inline
1436 struct ctf_field_class *ctf_field_class_copy(struct ctf_field_class *fc)
1437 {
1438 struct ctf_field_class *copy_fc = NULL;
1439
1440 if (!fc) {
1441 goto end;
1442 }
1443
1444 /*
1445 * Translation should not have happened yet.
1446 */
1447 BT_ASSERT(!fc->ir_fc);
1448
1449 switch (fc->type) {
1450 case CTF_FIELD_CLASS_TYPE_INT:
1451 copy_fc = (void *) _ctf_field_class_int_copy((void *) fc);
1452 break;
1453 case CTF_FIELD_CLASS_TYPE_ENUM:
1454 copy_fc = (void *) _ctf_field_class_enum_copy((void *) fc);
1455 break;
1456 case CTF_FIELD_CLASS_TYPE_FLOAT:
1457 copy_fc = (void *) _ctf_field_class_float_copy((void *) fc);
1458 break;
1459 case CTF_FIELD_CLASS_TYPE_STRING:
1460 copy_fc = (void *) _ctf_field_class_string_copy((void *) fc);
1461 break;
1462 case CTF_FIELD_CLASS_TYPE_STRUCT:
1463 copy_fc = (void *) _ctf_field_class_struct_copy((void *) fc);
1464 break;
1465 case CTF_FIELD_CLASS_TYPE_ARRAY:
1466 copy_fc = (void *) _ctf_field_class_array_copy((void *) fc);
1467 break;
1468 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
1469 copy_fc = (void *) _ctf_field_class_sequence_copy((void *) fc);
1470 break;
1471 case CTF_FIELD_CLASS_TYPE_VARIANT:
1472 copy_fc = (void *) _ctf_field_class_variant_copy((void *) fc);
1473 break;
1474 default:
1475 abort();
1476 }
1477
1478 copy_fc->type = fc->type;
1479 copy_fc->alignment = fc->alignment;
1480 copy_fc->in_ir = fc->in_ir;
1481
1482 end:
1483 return copy_fc;
1484 }
1485
1486 static inline
1487 struct ctf_event_class *ctf_event_class_create(void)
1488 {
1489 struct ctf_event_class *ec = g_new0(struct ctf_event_class, 1);
1490
1491 BT_ASSERT(ec);
1492 ec->name = g_string_new(NULL);
1493 BT_ASSERT(ec->name);
1494 ec->emf_uri = g_string_new(NULL);
1495 BT_ASSERT(ec->emf_uri);
1496 ec->is_log_level_set = false;
1497 return ec;
1498 }
1499
1500 static inline
1501 void ctf_event_class_set_log_level(struct ctf_event_class *ec,
1502 enum bt_event_class_log_level log_level)
1503 {
1504 BT_ASSERT(ec);
1505 ec->log_level = log_level;
1506 ec->is_log_level_set = true;
1507 }
1508
1509 static inline
1510 void ctf_event_class_destroy(struct ctf_event_class *ec)
1511 {
1512 if (!ec) {
1513 return;
1514 }
1515
1516 if (ec->name) {
1517 g_string_free(ec->name, TRUE);
1518 }
1519
1520 if (ec->emf_uri) {
1521 g_string_free(ec->emf_uri, TRUE);
1522 }
1523
1524 ctf_field_class_destroy(ec->spec_context_fc);
1525 ctf_field_class_destroy(ec->payload_fc);
1526 g_free(ec);
1527 }
1528
1529 static inline
1530 struct ctf_stream_class *ctf_stream_class_create(void)
1531 {
1532 struct ctf_stream_class *sc = g_new0(struct ctf_stream_class, 1);
1533
1534 BT_ASSERT(sc);
1535 sc->event_classes = g_ptr_array_new_with_free_func(
1536 (GDestroyNotify) ctf_event_class_destroy);
1537 BT_ASSERT(sc->event_classes);
1538 sc->event_classes_by_id = g_hash_table_new(g_direct_hash,
1539 g_direct_equal);
1540 BT_ASSERT(sc->event_classes_by_id);
1541 return sc;
1542 }
1543
1544 static inline
1545 void ctf_stream_class_destroy(struct ctf_stream_class *sc)
1546 {
1547 if (!sc) {
1548 return;
1549 }
1550
1551 if (sc->event_classes) {
1552 g_ptr_array_free(sc->event_classes, TRUE);
1553 }
1554
1555 if (sc->event_classes_by_id) {
1556 g_hash_table_destroy(sc->event_classes_by_id);
1557 }
1558
1559 ctf_field_class_destroy(sc->packet_context_fc);
1560 ctf_field_class_destroy(sc->event_header_fc);
1561 ctf_field_class_destroy(sc->event_common_context_fc);
1562 g_free(sc);
1563 }
1564
1565 static inline
1566 void ctf_stream_class_append_event_class(struct ctf_stream_class *sc,
1567 struct ctf_event_class *ec)
1568 {
1569 g_ptr_array_add(sc->event_classes, ec);
1570 g_hash_table_insert(sc->event_classes_by_id,
1571 GUINT_TO_POINTER((guint) ec->id), ec);
1572 }
1573
1574 static inline
1575 struct ctf_event_class *ctf_stream_class_borrow_event_class_by_id(
1576 struct ctf_stream_class *sc, uint64_t type)
1577 {
1578 BT_ASSERT(sc);
1579 return g_hash_table_lookup(sc->event_classes_by_id,
1580 GUINT_TO_POINTER((guint) type));
1581 }
1582
1583 static inline
1584 void _ctf_trace_class_env_entry_init(struct ctf_trace_class_env_entry *entry)
1585 {
1586 BT_ASSERT(entry);
1587 entry->name = g_string_new(NULL);
1588 BT_ASSERT(entry->name);
1589 entry->value.str = g_string_new(NULL);
1590 BT_ASSERT(entry->value.str);
1591 }
1592
1593 static inline
1594 void _ctf_trace_class_env_entry_fini(struct ctf_trace_class_env_entry *entry)
1595 {
1596 BT_ASSERT(entry);
1597
1598 if (entry->name) {
1599 g_string_free(entry->name, TRUE);
1600 }
1601
1602 if (entry->value.str) {
1603 g_string_free(entry->value.str, TRUE);
1604 }
1605 }
1606
1607 static inline
1608 struct ctf_clock_class *ctf_clock_class_create(void)
1609 {
1610 struct ctf_clock_class *cc = g_new0(struct ctf_clock_class, 1);
1611
1612 BT_ASSERT(cc);
1613 cc->name = g_string_new(NULL);
1614 BT_ASSERT(cc->name);
1615 cc->description = g_string_new(NULL);
1616 BT_ASSERT(cc->description);
1617 return cc;
1618 }
1619
1620 static inline
1621 void ctf_clock_class_destroy(struct ctf_clock_class *cc)
1622 {
1623 if (!cc) {
1624 return;
1625 }
1626
1627 if (cc->name) {
1628 g_string_free(cc->name, TRUE);
1629 }
1630
1631 if (cc->description) {
1632 g_string_free(cc->description, TRUE);
1633 }
1634
1635 bt_clock_class_put_ref(cc->ir_cc);
1636 g_free(cc);
1637 }
1638
1639 static inline
1640 struct ctf_trace_class *ctf_trace_class_create(void)
1641 {
1642 struct ctf_trace_class *tc = g_new0(struct ctf_trace_class, 1);
1643
1644 BT_ASSERT(tc);
1645 tc->default_byte_order = CTF_BYTE_ORDER_UNKNOWN;
1646 tc->clock_classes = g_ptr_array_new_with_free_func(
1647 (GDestroyNotify) ctf_clock_class_destroy);
1648 BT_ASSERT(tc->clock_classes);
1649 tc->stream_classes = g_ptr_array_new_with_free_func(
1650 (GDestroyNotify) ctf_stream_class_destroy);
1651 BT_ASSERT(tc->stream_classes);
1652 tc->env_entries = g_array_new(FALSE, TRUE,
1653 sizeof(struct ctf_trace_class_env_entry));
1654 return tc;
1655 }
1656
1657 static inline
1658 void ctf_trace_class_destroy(struct ctf_trace_class *tc)
1659 {
1660 if (!tc) {
1661 return;
1662 }
1663
1664 ctf_field_class_destroy(tc->packet_header_fc);
1665
1666 if (tc->clock_classes) {
1667 g_ptr_array_free(tc->clock_classes, TRUE);
1668 }
1669
1670 if (tc->stream_classes) {
1671 g_ptr_array_free(tc->stream_classes, TRUE);
1672 }
1673
1674 if (tc->env_entries) {
1675 uint64_t i;
1676
1677 for (i = 0; i < tc->env_entries->len; i++) {
1678 struct ctf_trace_class_env_entry *entry =
1679 &g_array_index(tc->env_entries,
1680 struct ctf_trace_class_env_entry, i);
1681
1682 _ctf_trace_class_env_entry_fini(entry);
1683 }
1684
1685 g_array_free(tc->env_entries, TRUE);
1686 }
1687
1688 g_free(tc);
1689 }
1690
1691 static inline
1692 void ctf_trace_class_append_env_entry(struct ctf_trace_class *tc,
1693 const char *name, enum ctf_trace_class_env_entry_type type,
1694 const char *str_value, int64_t i_value)
1695 {
1696 struct ctf_trace_class_env_entry *entry;
1697
1698 BT_ASSERT(tc);
1699 BT_ASSERT(name);
1700 g_array_set_size(tc->env_entries, tc->env_entries->len + 1);
1701
1702 entry = &g_array_index(tc->env_entries,
1703 struct ctf_trace_class_env_entry, tc->env_entries->len - 1);
1704 entry->type = type;
1705 _ctf_trace_class_env_entry_init(entry);
1706 g_string_assign(entry->name, name);
1707
1708 if (str_value) {
1709 g_string_assign(entry->value.str, str_value);
1710 }
1711
1712 entry->value.i = i_value;
1713 }
1714
1715 static inline
1716 struct ctf_stream_class *ctf_trace_class_borrow_stream_class_by_id(
1717 struct ctf_trace_class *tc, uint64_t id)
1718 {
1719 uint64_t i;
1720 struct ctf_stream_class *ret_sc = NULL;
1721
1722 BT_ASSERT(tc);
1723
1724 for (i = 0; i < tc->stream_classes->len; i++) {
1725 struct ctf_stream_class *sc = tc->stream_classes->pdata[i];
1726
1727 if (sc->id == id) {
1728 ret_sc = sc;
1729 goto end;
1730 }
1731 }
1732
1733 end:
1734 return ret_sc;
1735 }
1736
1737 static inline
1738 struct ctf_clock_class *ctf_trace_class_borrow_clock_class_by_name(
1739 struct ctf_trace_class *tc, const char *name)
1740 {
1741 uint64_t i;
1742 struct ctf_clock_class *ret_cc = NULL;
1743
1744 BT_ASSERT(tc);
1745 BT_ASSERT(name);
1746
1747 for (i = 0; i < tc->clock_classes->len; i++) {
1748 struct ctf_clock_class *cc = tc->clock_classes->pdata[i];
1749
1750 BT_ASSERT(cc->name);
1751 if (strcmp(cc->name->str, name) == 0) {
1752 ret_cc = cc;
1753 goto end;
1754 }
1755 }
1756
1757 end:
1758 return ret_cc;
1759 }
1760
1761 static inline
1762 struct ctf_trace_class_env_entry *ctf_trace_class_borrow_env_entry_by_index(
1763 struct ctf_trace_class *tc, uint64_t index)
1764 {
1765 BT_ASSERT(tc);
1766 BT_ASSERT(index < tc->env_entries->len);
1767 return &g_array_index(tc->env_entries, struct ctf_trace_class_env_entry,
1768 index);
1769 }
1770
1771 static inline
1772 struct ctf_trace_class_env_entry *ctf_trace_class_borrow_env_entry_by_name(
1773 struct ctf_trace_class *tc, const char *name)
1774 {
1775 struct ctf_trace_class_env_entry *ret_entry = NULL;
1776 uint64_t i;
1777
1778 BT_ASSERT(tc);
1779 BT_ASSERT(name);
1780
1781 for (i = 0; i < tc->env_entries->len; i++) {
1782 struct ctf_trace_class_env_entry *env_entry =
1783 ctf_trace_class_borrow_env_entry_by_index(tc, i);
1784
1785 if (strcmp(env_entry->name->str, name) == 0) {
1786 ret_entry = env_entry;
1787 goto end;
1788 }
1789 }
1790
1791 end:
1792 return ret_entry;
1793 }
1794
1795 #endif /* _CTF_META_H */
This page took 0.103452 seconds and 5 git commands to generate.