72d47d4aaf53313925039d66b85546f048e9603f
[babeltrace.git] / src / plugins / ctf / fs-sink / fs-sink-ctf-meta.h
1 #ifndef BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H
2 #define BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H
3
4 /*
5 * Copyright 2018-2019 - 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/assert.h"
21 #include "common/uuid.h"
22 #include <glib.h>
23 #include <stdint.h>
24 #include <string.h>
25 #include <stdbool.h>
26 #include <ctype.h>
27
28 enum fs_sink_ctf_field_class_type {
29 FS_SINK_CTF_FIELD_CLASS_TYPE_INT,
30 FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT,
31 FS_SINK_CTF_FIELD_CLASS_TYPE_STRING,
32 FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT,
33 FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY,
34 FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE,
35 FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT,
36 };
37
38 struct fs_sink_ctf_field_class {
39 enum fs_sink_ctf_field_class_type type;
40
41 /* Weak */
42 const bt_field_class *ir_fc;
43
44 unsigned int alignment;
45
46 /* Index of the field class within its own parent */
47 uint64_t index_in_parent;
48 };
49
50 struct fs_sink_ctf_field_class_bit_array {
51 struct fs_sink_ctf_field_class base;
52 unsigned int size;
53 };
54
55 struct fs_sink_ctf_field_class_int {
56 struct fs_sink_ctf_field_class_bit_array base;
57 bool is_signed;
58 };
59
60 struct fs_sink_ctf_field_class_float {
61 struct fs_sink_ctf_field_class_bit_array base;
62 };
63
64 struct fs_sink_ctf_field_class_string {
65 struct fs_sink_ctf_field_class base;
66 };
67
68 struct fs_sink_ctf_named_field_class {
69 GString *name;
70
71 /* Owned by this */
72 struct fs_sink_ctf_field_class *fc;
73 };
74
75 struct fs_sink_ctf_field_class_struct {
76 struct fs_sink_ctf_field_class base;
77
78 /* Array of `struct fs_sink_ctf_named_field_class` */
79 GArray *members;
80 };
81
82 struct fs_sink_ctf_field_class_variant {
83 struct fs_sink_ctf_field_class base;
84 GString *tag_ref;
85 bool tag_is_before;
86
87 /* Array of `struct fs_sink_ctf_named_field_class` */
88 GArray *options;
89 };
90
91 struct fs_sink_ctf_field_class_array_base {
92 struct fs_sink_ctf_field_class base;
93 struct fs_sink_ctf_field_class *elem_fc;
94 };
95
96 struct fs_sink_ctf_field_class_array {
97 struct fs_sink_ctf_field_class_array_base base;
98 uint64_t length;
99 };
100
101 struct fs_sink_ctf_field_class_sequence {
102 struct fs_sink_ctf_field_class_array_base base;
103 GString *length_ref;
104 bool length_is_before;
105 };
106
107 struct fs_sink_ctf_stream_class;
108
109 struct fs_sink_ctf_event_class {
110 /* Weak */
111 const bt_event_class *ir_ec;
112
113 /* Weak */
114 struct fs_sink_ctf_stream_class *sc;
115
116 /* Owned by this */
117 struct fs_sink_ctf_field_class *spec_context_fc;
118
119 /* Owned by this */
120 struct fs_sink_ctf_field_class *payload_fc;
121 };
122
123 struct fs_sink_ctf_trace;
124
125 struct fs_sink_ctf_stream_class {
126 /* Weak */
127 struct fs_sink_ctf_trace *trace;
128
129 /* Weak */
130 const bt_stream_class *ir_sc;
131
132 /* Weak */
133 const bt_clock_class *default_clock_class;
134
135 GString *default_clock_class_name;
136 bool has_packets;
137 bool packets_have_ts_begin;
138 bool packets_have_ts_end;
139 bool has_discarded_events;
140 bool discarded_events_has_ts;
141 bool discarded_packets_has_ts;
142
143 /* Owned by this */
144 struct fs_sink_ctf_field_class *packet_context_fc;
145
146 /* Owned by this */
147 struct fs_sink_ctf_field_class *event_common_context_fc;
148
149 /* Array of `struct fs_sink_ctf_event_class *` (owned by this) */
150 GPtrArray *event_classes;
151
152 /*
153 * `const bt_event_class *` (weak) ->
154 * `struct fs_sink_ctf_event_class *` (weak)
155 */
156 GHashTable *event_classes_from_ir;
157 };
158
159 struct fs_sink_ctf_trace {
160 /* Weak */
161 const bt_trace *ir_trace;
162
163 /* Weak */
164 const bt_trace_class *ir_tc;
165
166 bt_uuid_t uuid;
167
168 /* Array of `struct fs_sink_ctf_stream_class *` (owned by this) */
169 GPtrArray *stream_classes;
170 };
171
172 static inline
173 void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class *fc);
174
175 static inline
176 void _fs_sink_ctf_field_class_init(struct fs_sink_ctf_field_class *fc,
177 enum fs_sink_ctf_field_class_type type,
178 const bt_field_class *ir_fc, unsigned int alignment,
179 uint64_t index_in_parent)
180 {
181 BT_ASSERT(fc);
182 fc->type = type;
183 fc->ir_fc = ir_fc;
184 fc->alignment = alignment;
185 fc->index_in_parent = index_in_parent;
186 }
187
188 static inline
189 void _fs_sink_ctf_field_class_bit_array_init(
190 struct fs_sink_ctf_field_class_bit_array *fc,
191 enum fs_sink_ctf_field_class_type type,
192 const bt_field_class *ir_fc, unsigned int size,
193 uint64_t index_in_parent)
194 {
195 _fs_sink_ctf_field_class_init((void *) fc, type, ir_fc,
196 size % 8 == 0 ? 8 : 1, index_in_parent);
197 fc->size = size;
198 }
199
200 static inline
201 void _fs_sink_ctf_field_class_int_init(struct fs_sink_ctf_field_class_int *fc,
202 enum fs_sink_ctf_field_class_type type,
203 const bt_field_class *ir_fc, uint64_t index_in_parent)
204 {
205 bt_field_class_type ir_fc_type = bt_field_class_get_type(ir_fc);
206
207 _fs_sink_ctf_field_class_bit_array_init((void *) fc, type, ir_fc,
208 (unsigned int) bt_field_class_integer_get_field_value_range(
209 ir_fc),
210 index_in_parent);
211 fc->is_signed = (ir_fc_type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
212 ir_fc_type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION);
213 }
214
215 static inline
216 void _fs_sink_ctf_named_field_class_init(
217 struct fs_sink_ctf_named_field_class *named_fc)
218 {
219 BT_ASSERT(named_fc);
220 named_fc->name = g_string_new(NULL);
221 BT_ASSERT(named_fc->name);
222 }
223
224 static inline
225 void _fs_sink_ctf_named_field_class_fini(
226 struct fs_sink_ctf_named_field_class *named_fc)
227 {
228 BT_ASSERT(named_fc);
229
230 if (named_fc->name) {
231 g_string_free(named_fc->name, TRUE);
232 named_fc->name = NULL;
233 }
234
235 fs_sink_ctf_field_class_destroy(named_fc->fc);
236 named_fc->fc = NULL;
237 }
238
239 static inline
240 struct fs_sink_ctf_field_class_int *fs_sink_ctf_field_class_int_create(
241 const bt_field_class *ir_fc, uint64_t index_in_parent)
242 {
243 struct fs_sink_ctf_field_class_int *fc =
244 g_new0(struct fs_sink_ctf_field_class_int, 1);
245
246 BT_ASSERT(fc);
247 _fs_sink_ctf_field_class_int_init(fc, FS_SINK_CTF_FIELD_CLASS_TYPE_INT,
248 ir_fc, index_in_parent);
249 return fc;
250 }
251
252 static inline
253 struct fs_sink_ctf_field_class_float *fs_sink_ctf_field_class_float_create(
254 const bt_field_class *ir_fc, uint64_t index_in_parent)
255 {
256 struct fs_sink_ctf_field_class_float *fc =
257 g_new0(struct fs_sink_ctf_field_class_float, 1);
258
259 BT_ASSERT(fc);
260 _fs_sink_ctf_field_class_bit_array_init((void *) fc,
261 FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT,
262 ir_fc, bt_field_class_real_is_single_precision(ir_fc) ? 32 : 64,
263 index_in_parent);
264 return fc;
265 }
266
267 static inline
268 struct fs_sink_ctf_field_class_string *fs_sink_ctf_field_class_string_create(
269 const bt_field_class *ir_fc, uint64_t index_in_parent)
270 {
271 struct fs_sink_ctf_field_class_string *fc =
272 g_new0(struct fs_sink_ctf_field_class_string, 1);
273
274 BT_ASSERT(fc);
275 _fs_sink_ctf_field_class_init((void *) fc,
276 FS_SINK_CTF_FIELD_CLASS_TYPE_STRING, ir_fc,
277 8, index_in_parent);
278 return fc;
279 }
280
281 static inline
282 struct fs_sink_ctf_field_class_struct *fs_sink_ctf_field_class_struct_create_empty(
283 const bt_field_class *ir_fc, uint64_t index_in_parent)
284 {
285 struct fs_sink_ctf_field_class_struct *fc =
286 g_new0(struct fs_sink_ctf_field_class_struct, 1);
287
288 BT_ASSERT(fc);
289 _fs_sink_ctf_field_class_init((void *) fc,
290 FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT, ir_fc, 1, index_in_parent);
291 fc->members = g_array_new(FALSE, TRUE,
292 sizeof(struct fs_sink_ctf_named_field_class));
293 BT_ASSERT(fc->members);
294 return fc;
295 }
296
297 static inline
298 struct fs_sink_ctf_field_class_variant *fs_sink_ctf_field_class_variant_create_empty(
299 const bt_field_class *ir_fc, uint64_t index_in_parent)
300 {
301 struct fs_sink_ctf_field_class_variant *fc =
302 g_new0(struct fs_sink_ctf_field_class_variant, 1);
303
304 BT_ASSERT(fc);
305 _fs_sink_ctf_field_class_init((void *) fc,
306 FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT, ir_fc,
307 1, index_in_parent);
308 fc->options = g_array_new(FALSE, TRUE,
309 sizeof(struct fs_sink_ctf_named_field_class));
310 BT_ASSERT(fc->options);
311 fc->tag_ref = g_string_new(NULL);
312 BT_ASSERT(fc->tag_ref);
313 fc->tag_is_before =
314 bt_field_class_variant_borrow_selector_field_path_const(ir_fc) ==
315 NULL;
316 return fc;
317 }
318
319 static inline
320 struct fs_sink_ctf_field_class_array *fs_sink_ctf_field_class_array_create_empty(
321 const bt_field_class *ir_fc, uint64_t index_in_parent)
322 {
323 struct fs_sink_ctf_field_class_array *fc =
324 g_new0(struct fs_sink_ctf_field_class_array, 1);
325
326 BT_ASSERT(fc);
327 _fs_sink_ctf_field_class_init((void *) fc,
328 FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY, ir_fc,
329 1, index_in_parent);
330 fc->length = bt_field_class_static_array_get_length(ir_fc);
331 return fc;
332 }
333
334 static inline
335 struct fs_sink_ctf_field_class_sequence *fs_sink_ctf_field_class_sequence_create_empty(
336 const bt_field_class *ir_fc, uint64_t index_in_parent)
337 {
338 struct fs_sink_ctf_field_class_sequence *fc =
339 g_new0(struct fs_sink_ctf_field_class_sequence, 1);
340
341 BT_ASSERT(fc);
342 _fs_sink_ctf_field_class_init((void *) fc,
343 FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE,
344 ir_fc, 1, index_in_parent);
345 fc->length_ref = g_string_new(NULL);
346 BT_ASSERT(fc->length_ref);
347 fc->length_is_before =
348 bt_field_class_dynamic_array_borrow_length_field_path_const(ir_fc) ==
349 NULL;
350 return fc;
351 }
352
353 static inline
354 struct fs_sink_ctf_named_field_class *
355 fs_sink_ctf_field_class_struct_borrow_member_by_index(
356 struct fs_sink_ctf_field_class_struct *fc, uint64_t index);
357
358 static inline
359 struct fs_sink_ctf_named_field_class *
360 fs_sink_ctf_field_class_variant_borrow_option_by_index(
361 struct fs_sink_ctf_field_class_variant *fc, uint64_t index);
362
363 static inline
364 void _fs_sink_ctf_field_class_fini(struct fs_sink_ctf_field_class *fc)
365 {
366 BT_ASSERT(fc);
367 }
368
369 static inline
370 void _fs_sink_ctf_field_class_int_destroy(
371 struct fs_sink_ctf_field_class_int *fc)
372 {
373 BT_ASSERT(fc);
374 _fs_sink_ctf_field_class_fini((void *) fc);
375 g_free(fc);
376 }
377
378 static inline
379 void _fs_sink_ctf_field_class_float_destroy(
380 struct fs_sink_ctf_field_class_float *fc)
381 {
382 BT_ASSERT(fc);
383 _fs_sink_ctf_field_class_fini((void *) fc);
384 g_free(fc);
385 }
386
387 static inline
388 void _fs_sink_ctf_field_class_string_destroy(
389 struct fs_sink_ctf_field_class_string *fc)
390 {
391 BT_ASSERT(fc);
392 _fs_sink_ctf_field_class_fini((void *) fc);
393 g_free(fc);
394 }
395
396 static inline
397 void _fs_sink_ctf_field_class_struct_destroy(
398 struct fs_sink_ctf_field_class_struct *fc)
399 {
400 BT_ASSERT(fc);
401 _fs_sink_ctf_field_class_fini((void *) fc);
402
403 if (fc->members) {
404 uint64_t i;
405
406 for (i = 0; i < fc->members->len; i++) {
407 struct fs_sink_ctf_named_field_class *named_fc =
408 fs_sink_ctf_field_class_struct_borrow_member_by_index(
409 fc, i);
410
411 _fs_sink_ctf_named_field_class_fini(named_fc);
412 }
413
414 g_array_free(fc->members, TRUE);
415 fc->members = NULL;
416 }
417
418 g_free(fc);
419 }
420
421 static inline
422 void _fs_sink_ctf_field_class_array_base_fini(
423 struct fs_sink_ctf_field_class_array_base *fc)
424 {
425 BT_ASSERT(fc);
426 _fs_sink_ctf_field_class_fini((void *) fc);
427 fs_sink_ctf_field_class_destroy(fc->elem_fc);
428 fc->elem_fc = NULL;
429 }
430
431 static inline
432 void _fs_sink_ctf_field_class_array_destroy(
433 struct fs_sink_ctf_field_class_array *fc)
434 {
435 BT_ASSERT(fc);
436 _fs_sink_ctf_field_class_array_base_fini((void *) fc);
437 g_free(fc);
438 }
439
440 static inline
441 void _fs_sink_ctf_field_class_sequence_destroy(
442 struct fs_sink_ctf_field_class_sequence *fc)
443 {
444 BT_ASSERT(fc);
445 _fs_sink_ctf_field_class_array_base_fini((void *) fc);
446
447 if (fc->length_ref) {
448 g_string_free(fc->length_ref, TRUE);
449 fc->length_ref = NULL;
450 }
451
452 g_free(fc);
453 }
454
455 static inline
456 void _fs_sink_ctf_field_class_variant_destroy(
457 struct fs_sink_ctf_field_class_variant *fc)
458 {
459 BT_ASSERT(fc);
460 _fs_sink_ctf_field_class_fini((void *) fc);
461
462 if (fc->options) {
463 uint64_t i;
464
465 for (i = 0; i < fc->options->len; i++) {
466 struct fs_sink_ctf_named_field_class *named_fc =
467 fs_sink_ctf_field_class_variant_borrow_option_by_index(
468 fc, i);
469
470 _fs_sink_ctf_named_field_class_fini(named_fc);
471 }
472
473 g_array_free(fc->options, TRUE);
474 fc->options = NULL;
475 }
476
477 if (fc->tag_ref) {
478 g_string_free(fc->tag_ref, TRUE);
479 fc->tag_ref = NULL;
480 }
481
482 g_free(fc);
483 }
484
485 static inline
486 void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class *fc)
487 {
488 if (!fc) {
489 return;
490 }
491
492 switch (fc->type) {
493 case FS_SINK_CTF_FIELD_CLASS_TYPE_INT:
494 _fs_sink_ctf_field_class_int_destroy((void *) fc);
495 break;
496 case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT:
497 _fs_sink_ctf_field_class_float_destroy((void *) fc);
498 break;
499 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING:
500 _fs_sink_ctf_field_class_string_destroy((void *) fc);
501 break;
502 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT:
503 _fs_sink_ctf_field_class_struct_destroy((void *) fc);
504 break;
505 case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY:
506 _fs_sink_ctf_field_class_array_destroy((void *) fc);
507 break;
508 case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE:
509 _fs_sink_ctf_field_class_sequence_destroy((void *) fc);
510 break;
511 case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT:
512 _fs_sink_ctf_field_class_variant_destroy((void *) fc);
513 break;
514 default:
515 abort();
516 }
517 }
518
519 static inline
520 struct fs_sink_ctf_named_field_class *
521 fs_sink_ctf_field_class_struct_borrow_member_by_index(
522 struct fs_sink_ctf_field_class_struct *fc, uint64_t index)
523 {
524 BT_ASSERT(fc);
525 BT_ASSERT(index < fc->members->len);
526 return &g_array_index(fc->members, struct fs_sink_ctf_named_field_class,
527 index);
528 }
529
530 static inline
531 struct fs_sink_ctf_named_field_class *
532 fs_sink_ctf_field_class_struct_borrow_member_by_name(
533 struct fs_sink_ctf_field_class_struct *fc, const char *name)
534 {
535 uint64_t i;
536 struct fs_sink_ctf_named_field_class *ret_named_fc = NULL;
537
538 BT_ASSERT(fc);
539 BT_ASSERT(name);
540
541 for (i = 0; i < fc->members->len; i++) {
542 struct fs_sink_ctf_named_field_class *named_fc =
543 fs_sink_ctf_field_class_struct_borrow_member_by_index(
544 fc, i);
545
546 if (strcmp(name, named_fc->name->str) == 0) {
547 ret_named_fc = named_fc;
548 goto end;
549 }
550 }
551
552 end:
553 return ret_named_fc;
554 }
555
556 static inline
557 struct fs_sink_ctf_field_class *
558 fs_sink_ctf_field_class_struct_borrow_member_field_class_by_name(
559 struct fs_sink_ctf_field_class_struct *struct_fc, const char *name)
560 {
561 struct fs_sink_ctf_named_field_class *named_fc = NULL;
562 struct fs_sink_ctf_field_class *fc = NULL;
563
564 if (!struct_fc) {
565 goto end;
566 }
567
568 named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_name(
569 struct_fc, name);
570 if (!named_fc) {
571 goto end;
572 }
573
574 fc = named_fc->fc;
575
576 end:
577 return fc;
578 }
579
580 static inline
581 struct fs_sink_ctf_field_class_int *
582 fs_sink_ctf_field_class_struct_borrow_member_int_field_class_by_name(
583 struct fs_sink_ctf_field_class_struct *struct_fc,
584 const char *name)
585 {
586 struct fs_sink_ctf_field_class_int *int_fc = NULL;
587
588 int_fc = (void *)
589 fs_sink_ctf_field_class_struct_borrow_member_field_class_by_name(
590 struct_fc, name);
591 if (!int_fc) {
592 goto end;
593 }
594
595 if (int_fc->base.base.type != FS_SINK_CTF_FIELD_CLASS_TYPE_INT) {
596 int_fc = NULL;
597 goto end;
598 }
599
600 end:
601 return int_fc;
602 }
603
604 static inline
605 void fs_sink_ctf_field_class_struct_align_at_least(
606 struct fs_sink_ctf_field_class_struct *fc,
607 unsigned int alignment)
608 {
609 if (alignment > fc->base.alignment) {
610 fc->base.alignment = alignment;
611 }
612 }
613
614 static inline
615 void fs_sink_ctf_field_class_struct_append_member(
616 struct fs_sink_ctf_field_class_struct *fc,
617 const char *name, struct fs_sink_ctf_field_class *member_fc)
618 {
619 struct fs_sink_ctf_named_field_class *named_fc;
620
621 BT_ASSERT(fc);
622 BT_ASSERT(name);
623 g_array_set_size(fc->members, fc->members->len + 1);
624
625 named_fc = &g_array_index(fc->members,
626 struct fs_sink_ctf_named_field_class, fc->members->len - 1);
627 _fs_sink_ctf_named_field_class_init(named_fc);
628 g_string_assign(named_fc->name, name);
629 named_fc->fc = member_fc;
630 fs_sink_ctf_field_class_struct_align_at_least(fc, member_fc->alignment);
631 }
632
633 static inline
634 struct fs_sink_ctf_named_field_class *
635 fs_sink_ctf_field_class_variant_borrow_option_by_index(
636 struct fs_sink_ctf_field_class_variant *fc, uint64_t index)
637 {
638 BT_ASSERT(fc);
639 BT_ASSERT(index < fc->options->len);
640 return &g_array_index(fc->options, struct fs_sink_ctf_named_field_class,
641 index);
642 }
643
644 static inline
645 struct fs_sink_ctf_named_field_class *
646 fs_sink_ctf_field_class_variant_borrow_option_by_name(
647 struct fs_sink_ctf_field_class_variant *fc, const char *name)
648 {
649 uint64_t i;
650 struct fs_sink_ctf_named_field_class *ret_named_fc = NULL;
651
652 BT_ASSERT(fc);
653 BT_ASSERT(name);
654
655 for (i = 0; i < fc->options->len; i++) {
656 struct fs_sink_ctf_named_field_class *named_fc =
657 fs_sink_ctf_field_class_variant_borrow_option_by_index(
658 fc, i);
659
660 if (strcmp(name, named_fc->name->str) == 0) {
661 ret_named_fc = named_fc;
662 goto end;
663 }
664 }
665
666 end:
667 return ret_named_fc;
668 }
669
670 static inline
671 void fs_sink_ctf_field_class_variant_append_option(
672 struct fs_sink_ctf_field_class_variant *fc,
673 const char *name, struct fs_sink_ctf_field_class *option_fc)
674 {
675 struct fs_sink_ctf_named_field_class *named_fc;
676
677 BT_ASSERT(fc);
678 BT_ASSERT(name);
679 g_array_set_size(fc->options, fc->options->len + 1);
680
681 named_fc = &g_array_index(fc->options,
682 struct fs_sink_ctf_named_field_class, fc->options->len - 1);
683 _fs_sink_ctf_named_field_class_init(named_fc);
684 g_string_assign(named_fc->name, name);
685 named_fc->fc = option_fc;
686 }
687
688 static inline
689 struct fs_sink_ctf_event_class *fs_sink_ctf_event_class_create(
690 struct fs_sink_ctf_stream_class *sc,
691 const bt_event_class *ir_ec)
692 {
693 struct fs_sink_ctf_event_class *ec =
694 g_new0(struct fs_sink_ctf_event_class, 1);
695
696 BT_ASSERT(sc);
697 BT_ASSERT(ir_ec);
698 BT_ASSERT(ec);
699 ec->ir_ec = ir_ec;
700 ec->sc = sc;
701 g_ptr_array_add(sc->event_classes, ec);
702 g_hash_table_insert(sc->event_classes_from_ir, (gpointer) ir_ec, ec);
703 return ec;
704 }
705
706 static inline
707 void fs_sink_ctf_event_class_destroy(struct fs_sink_ctf_event_class *ec)
708 {
709 if (!ec) {
710 return;
711 }
712
713 fs_sink_ctf_field_class_destroy(ec->spec_context_fc);
714 ec->spec_context_fc = NULL;
715 fs_sink_ctf_field_class_destroy(ec->payload_fc);
716 ec->payload_fc = NULL;
717 g_free(ec);
718 }
719
720 static inline
721 struct fs_sink_ctf_stream_class *fs_sink_ctf_stream_class_create(
722 struct fs_sink_ctf_trace *trace,
723 const bt_stream_class *ir_sc)
724 {
725 struct fs_sink_ctf_stream_class *sc =
726 g_new0(struct fs_sink_ctf_stream_class, 1);
727
728 BT_ASSERT(trace);
729 BT_ASSERT(ir_sc);
730 BT_ASSERT(sc);
731 sc->trace = trace;
732 sc->ir_sc = ir_sc;
733 sc->default_clock_class =
734 bt_stream_class_borrow_default_clock_class_const(ir_sc);
735 sc->default_clock_class_name = g_string_new(NULL);
736 BT_ASSERT(sc->default_clock_class_name);
737 sc->event_classes = g_ptr_array_new_with_free_func(
738 (GDestroyNotify) fs_sink_ctf_event_class_destroy);
739 BT_ASSERT(sc->event_classes);
740 sc->event_classes_from_ir = g_hash_table_new(g_direct_hash,
741 g_direct_equal);
742 BT_ASSERT(sc->event_classes_from_ir);
743 sc->has_packets = bt_stream_class_supports_packets(ir_sc);
744 sc->packets_have_ts_begin =
745 bt_stream_class_packets_have_beginning_default_clock_snapshot(
746 ir_sc);
747 sc->packets_have_ts_end =
748 bt_stream_class_packets_have_end_default_clock_snapshot(ir_sc);
749 sc->has_discarded_events =
750 bt_stream_class_supports_discarded_events(ir_sc);
751
752 if (sc->has_discarded_events) {
753 sc->discarded_events_has_ts =
754 bt_stream_class_discarded_events_have_default_clock_snapshots(
755 ir_sc);
756 }
757
758 if (bt_stream_class_supports_discarded_packets(ir_sc)) {
759 sc->discarded_packets_has_ts =
760 bt_stream_class_discarded_packets_have_default_clock_snapshots(
761 ir_sc);
762 }
763
764 g_ptr_array_add(trace->stream_classes, sc);
765 return sc;
766 }
767
768 static inline
769 void fs_sink_ctf_stream_class_destroy(struct fs_sink_ctf_stream_class *sc)
770 {
771 if (!sc) {
772 return;
773 }
774
775 if (sc->default_clock_class_name) {
776 g_string_free(sc->default_clock_class_name, TRUE);
777 sc->default_clock_class_name = NULL;
778 }
779
780 if (sc->event_classes) {
781 g_ptr_array_free(sc->event_classes, TRUE);
782 sc->event_classes = NULL;
783 }
784
785 if (sc->event_classes_from_ir) {
786 g_hash_table_destroy(sc->event_classes_from_ir);
787 sc->event_classes_from_ir = NULL;
788 }
789
790 fs_sink_ctf_field_class_destroy(sc->packet_context_fc);
791 sc->packet_context_fc = NULL;
792 fs_sink_ctf_field_class_destroy(sc->event_common_context_fc);
793 sc->event_common_context_fc = NULL;
794 g_free(sc);
795 }
796
797 static inline
798 void fs_sink_ctf_stream_class_append_event_class(
799 struct fs_sink_ctf_stream_class *sc,
800 struct fs_sink_ctf_event_class *ec)
801 {
802 g_ptr_array_add(sc->event_classes, ec);
803 }
804
805 static inline
806 void fs_sink_ctf_trace_destroy(struct fs_sink_ctf_trace *trace)
807 {
808 if (!trace) {
809 return;
810 }
811
812 if (trace->stream_classes) {
813 g_ptr_array_free(trace->stream_classes, TRUE);
814 trace->stream_classes = NULL;
815 }
816
817 g_free(trace);
818 }
819
820 static inline
821 struct fs_sink_ctf_trace *fs_sink_ctf_trace_create(const bt_trace *ir_trace)
822 {
823 struct fs_sink_ctf_trace *trace =
824 g_new0(struct fs_sink_ctf_trace, 1);
825
826 BT_ASSERT(trace);
827
828 bt_uuid_generate(trace->uuid);
829
830 trace->ir_trace = ir_trace;
831 trace->ir_tc = bt_trace_borrow_class_const(ir_trace);
832 trace->stream_classes = g_ptr_array_new_with_free_func(
833 (GDestroyNotify) fs_sink_ctf_stream_class_destroy);
834 BT_ASSERT(trace->stream_classes);
835
836 return trace;
837 }
838
839 static inline
840 bool fs_sink_ctf_ist_valid_identifier(const char *name)
841 {
842 const char *at;
843 uint64_t i;
844 bool ist_valid = true;
845 static const char *reserved_keywords[] = {
846 "align",
847 "callsite",
848 "const",
849 "char",
850 "clock",
851 "double",
852 "enum",
853 "env",
854 "event",
855 "floating_point",
856 "float",
857 "integer",
858 "int",
859 "long",
860 "short",
861 "signed",
862 "stream",
863 "string",
864 "struct",
865 "trace",
866 "typealias",
867 "typedef",
868 "unsigned",
869 "variant",
870 "void",
871 "_Bool",
872 "_Complex",
873 "_Imaginary",
874 };
875
876 /* Make sure the name is not a reserved keyword */
877 for (i = 0; i < sizeof(reserved_keywords) / sizeof(*reserved_keywords);
878 i++) {
879 if (strcmp(name, reserved_keywords[i]) == 0) {
880 ist_valid = false;
881 goto end;
882 }
883 }
884
885 /* Make sure the name is not an empty string */
886 if (strlen(name) == 0) {
887 ist_valid = false;
888 goto end;
889 }
890
891 /* Make sure the name starts with a letter or `_` */
892 if (!isalpha(name[0]) && name[0] != '_') {
893 ist_valid = false;
894 goto end;
895 }
896
897 /* Make sure the name only contains letters, digits, and `_` */
898 for (at = name; *at != '\0'; at++) {
899 if (!isalnum(*at) && *at != '_') {
900 ist_valid = false;
901 goto end;
902 }
903 }
904
905 end:
906 return ist_valid;
907 }
908
909 static inline
910 int fs_sink_ctf_protect_name(GString *name)
911 {
912 int ret = 0;
913
914 if (!fs_sink_ctf_ist_valid_identifier(name->str)) {
915 ret = -1;
916 goto end;
917 }
918
919 /* Prepend `_` to protect it */
920 g_string_prepend_c(name, '_');
921
922 end:
923 return ret;
924 }
925
926 #endif /* BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H */
This page took 0.062514 seconds and 3 git commands to generate.