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