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