lib: remove CTF concepts of packet and event headers
[babeltrace.git] / plugins / ctf / common / metadata / ctf-meta-translate.c
1 /*
2 * Copyright 2018 - Philippe Proulx <pproulx@efficios.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 */
14
15 #define BT_LOG_TAG "PLUGIN-CTF-METADATA-META-TRANSLATE"
16 #include "logging.h"
17
18 #include <babeltrace/babeltrace.h>
19 #include <babeltrace/babeltrace-internal.h>
20 #include <babeltrace/assert-internal.h>
21 #include <glib.h>
22 #include <stdint.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 #include "ctf-meta-visitors.h"
27
28 struct ctx {
29 bt_trace_class *ir_tc;
30 bt_stream_class *ir_sc;
31 struct ctf_trace_class *tc;
32 struct ctf_stream_class *sc;
33 struct ctf_event_class *ec;
34 enum ctf_scope scope;
35 };
36
37 static inline
38 bt_field_class *ctf_field_class_to_ir(struct ctx *ctx,
39 struct ctf_field_class *fc);
40
41 static inline
42 void ctf_field_class_int_set_props(struct ctf_field_class_int *fc,
43 bt_field_class *ir_fc)
44 {
45 bt_field_class_integer_set_field_value_range(ir_fc,
46 fc->base.size);
47 bt_field_class_integer_set_preferred_display_base(ir_fc,
48 fc->disp_base);
49 }
50
51 static inline
52 bt_field_class *ctf_field_class_int_to_ir(struct ctx *ctx,
53 struct ctf_field_class_int *fc)
54 {
55 bt_field_class *ir_fc;
56
57 if (fc->is_signed) {
58 ir_fc = bt_field_class_signed_integer_create(ctx->ir_tc);
59 } else {
60 ir_fc = bt_field_class_unsigned_integer_create(ctx->ir_tc);
61 }
62
63 BT_ASSERT(ir_fc);
64 ctf_field_class_int_set_props(fc, ir_fc);
65 return ir_fc;
66 }
67
68 static inline
69 bt_field_class *ctf_field_class_enum_to_ir(struct ctx *ctx,
70 struct ctf_field_class_enum *fc)
71 {
72 int ret;
73 bt_field_class *ir_fc;
74 uint64_t i;
75
76 if (fc->base.is_signed) {
77 ir_fc = bt_field_class_signed_enumeration_create(ctx->ir_tc);
78 } else {
79 ir_fc = bt_field_class_unsigned_enumeration_create(ctx->ir_tc);
80 }
81
82 BT_ASSERT(ir_fc);
83 ctf_field_class_int_set_props((void *) fc, ir_fc);
84
85 for (i = 0; i < fc->mappings->len; i++) {
86 struct ctf_field_class_enum_mapping *mapping =
87 ctf_field_class_enum_borrow_mapping_by_index(fc, i);
88
89 if (fc->base.is_signed) {
90 ret = bt_field_class_signed_enumeration_map_range(
91 ir_fc, mapping->label->str,
92 mapping->range.lower.i, mapping->range.upper.i);
93 } else {
94 ret = bt_field_class_unsigned_enumeration_map_range(
95 ir_fc, mapping->label->str,
96 mapping->range.lower.u, mapping->range.upper.u);
97 }
98
99 BT_ASSERT(ret == 0);
100 }
101
102 return ir_fc;
103 }
104
105 static inline
106 bt_field_class *ctf_field_class_float_to_ir(struct ctx *ctx,
107 struct ctf_field_class_float *fc)
108 {
109 bt_field_class *ir_fc;
110
111 ir_fc = bt_field_class_real_create(ctx->ir_tc);
112 BT_ASSERT(ir_fc);
113
114 if (fc->base.size == 32) {
115 bt_field_class_real_set_is_single_precision(ir_fc,
116 BT_TRUE);
117 }
118
119 return ir_fc;
120 }
121
122 static inline
123 bt_field_class *ctf_field_class_string_to_ir(struct ctx *ctx,
124 struct ctf_field_class_string *fc)
125 {
126 bt_field_class *ir_fc = bt_field_class_string_create(ctx->ir_tc);
127
128 BT_ASSERT(ir_fc);
129 return ir_fc;
130 }
131
132 static inline
133 void translate_struct_field_class_members(struct ctx *ctx,
134 struct ctf_field_class_struct *fc, bt_field_class *ir_fc,
135 bool with_header_prefix,
136 struct ctf_field_class_struct *context_fc)
137 {
138 uint64_t i;
139 int ret;
140
141 for (i = 0; i < fc->members->len; i++) {
142 struct ctf_named_field_class *named_fc =
143 ctf_field_class_struct_borrow_member_by_index(fc, i);
144 bt_field_class *member_ir_fc;
145 const char *name = named_fc->name->str;
146
147 if (!named_fc->fc->in_ir) {
148 continue;
149 }
150
151 member_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc);
152 BT_ASSERT(member_ir_fc);
153 ret = bt_field_class_structure_append_member(ir_fc, name,
154 member_ir_fc);
155 BT_ASSERT(ret == 0);
156 bt_field_class_put_ref(member_ir_fc);
157 }
158 }
159
160 static inline
161 bt_field_class *ctf_field_class_struct_to_ir(struct ctx *ctx,
162 struct ctf_field_class_struct *fc)
163 {
164 bt_field_class *ir_fc = bt_field_class_structure_create(ctx->ir_tc);
165
166 BT_ASSERT(ir_fc);
167 translate_struct_field_class_members(ctx, fc, ir_fc, false, NULL);
168 return ir_fc;
169 }
170
171 static inline
172 bt_field_class *borrow_ir_fc_from_field_path(struct ctx *ctx,
173 struct ctf_field_path *field_path)
174 {
175 bt_field_class *ir_fc = NULL;
176 struct ctf_field_class *fc = ctf_field_path_borrow_field_class(
177 field_path, ctx->tc, ctx->sc, ctx->ec);
178
179 BT_ASSERT(fc);
180
181 if (fc->in_ir) {
182 ir_fc = fc->ir_fc;
183 }
184
185 return ir_fc;
186 }
187
188 static inline
189 bt_field_class *ctf_field_class_variant_to_ir(struct ctx *ctx,
190 struct ctf_field_class_variant *fc)
191 {
192 int ret;
193 bt_field_class *ir_fc = bt_field_class_variant_create(ctx->ir_tc);
194 uint64_t i;
195
196 BT_ASSERT(ir_fc);
197
198 if (fc->tag_path.root != CTF_SCOPE_PACKET_HEADER &&
199 fc->tag_path.root != CTF_SCOPE_EVENT_HEADER) {
200 ret = bt_field_class_variant_set_selector_field_class(
201 ir_fc, borrow_ir_fc_from_field_path(ctx,
202 &fc->tag_path));
203 BT_ASSERT(ret == 0);
204 }
205
206 for (i = 0; i < fc->options->len; i++) {
207 struct ctf_named_field_class *named_fc =
208 ctf_field_class_variant_borrow_option_by_index(fc, i);
209 bt_field_class *option_ir_fc;
210
211 BT_ASSERT(named_fc->fc->in_ir);
212 option_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc);
213 BT_ASSERT(option_ir_fc);
214 ret = bt_field_class_variant_append_option(
215 ir_fc, named_fc->name->str, option_ir_fc);
216 BT_ASSERT(ret == 0);
217 bt_field_class_put_ref(option_ir_fc);
218 }
219
220 return ir_fc;
221 }
222
223 static inline
224 bt_field_class *ctf_field_class_array_to_ir(struct ctx *ctx,
225 struct ctf_field_class_array *fc)
226 {
227 bt_field_class *ir_fc;
228 bt_field_class *elem_ir_fc;
229
230 if (fc->base.is_text) {
231 ir_fc = bt_field_class_string_create(ctx->ir_tc);
232 BT_ASSERT(ir_fc);
233 goto end;
234 }
235
236 elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc);
237 BT_ASSERT(elem_ir_fc);
238 ir_fc = bt_field_class_static_array_create(ctx->ir_tc, elem_ir_fc,
239 fc->length);
240 BT_ASSERT(ir_fc);
241 bt_field_class_put_ref(elem_ir_fc);
242
243 end:
244 return ir_fc;
245 }
246
247 static inline
248 bt_field_class *ctf_field_class_sequence_to_ir(struct ctx *ctx,
249 struct ctf_field_class_sequence *fc)
250 {
251 int ret;
252 bt_field_class *ir_fc;
253 bt_field_class *elem_ir_fc;
254
255 if (fc->base.is_text) {
256 ir_fc = bt_field_class_string_create(ctx->ir_tc);
257 BT_ASSERT(ir_fc);
258 goto end;
259 }
260
261 elem_ir_fc = ctf_field_class_to_ir(ctx, fc->base.elem_fc);
262 BT_ASSERT(elem_ir_fc);
263 ir_fc = bt_field_class_dynamic_array_create(ctx->ir_tc, elem_ir_fc);
264 BT_ASSERT(ir_fc);
265 bt_field_class_put_ref(elem_ir_fc);
266 BT_ASSERT(ir_fc);
267
268 if (fc->length_path.root != CTF_SCOPE_PACKET_HEADER &&
269 fc->length_path.root != CTF_SCOPE_EVENT_HEADER) {
270 ret = bt_field_class_dynamic_array_set_length_field_class(
271 ir_fc, borrow_ir_fc_from_field_path(ctx, &fc->length_path));
272 BT_ASSERT(ret == 0);
273 }
274
275 end:
276 return ir_fc;
277 }
278
279 static inline
280 bt_field_class *ctf_field_class_to_ir(struct ctx *ctx,
281 struct ctf_field_class *fc)
282 {
283 bt_field_class *ir_fc = NULL;
284
285 BT_ASSERT(fc);
286 BT_ASSERT(fc->in_ir);
287
288 switch (fc->type) {
289 case CTF_FIELD_CLASS_TYPE_INT:
290 ir_fc = ctf_field_class_int_to_ir(ctx, (void *) fc);
291 break;
292 case CTF_FIELD_CLASS_TYPE_ENUM:
293 ir_fc = ctf_field_class_enum_to_ir(ctx, (void *) fc);
294 break;
295 case CTF_FIELD_CLASS_TYPE_FLOAT:
296 ir_fc = ctf_field_class_float_to_ir(ctx, (void *) fc);
297 break;
298 case CTF_FIELD_CLASS_TYPE_STRING:
299 ir_fc = ctf_field_class_string_to_ir(ctx, (void *) fc);
300 break;
301 case CTF_FIELD_CLASS_TYPE_STRUCT:
302 ir_fc = ctf_field_class_struct_to_ir(ctx, (void *) fc);
303 break;
304 case CTF_FIELD_CLASS_TYPE_ARRAY:
305 ir_fc = ctf_field_class_array_to_ir(ctx, (void *) fc);
306 break;
307 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
308 ir_fc = ctf_field_class_sequence_to_ir(ctx, (void *) fc);
309 break;
310 case CTF_FIELD_CLASS_TYPE_VARIANT:
311 ir_fc = ctf_field_class_variant_to_ir(ctx, (void *) fc);
312 break;
313 default:
314 abort();
315 }
316
317 fc->ir_fc = ir_fc;
318 return ir_fc;
319 }
320
321 static inline
322 bool ctf_field_class_struct_has_immediate_member_in_ir(
323 struct ctf_field_class_struct *fc)
324 {
325 uint64_t i;
326 bool has_immediate_member_in_ir = false;
327
328 for (i = 0; i < fc->members->len; i++) {
329 struct ctf_named_field_class *named_fc =
330 ctf_field_class_struct_borrow_member_by_index(fc, i);
331
332 if (named_fc->fc->in_ir) {
333 has_immediate_member_in_ir = true;
334 goto end;
335 }
336 }
337
338 end:
339 return has_immediate_member_in_ir;
340 }
341
342 static inline
343 bt_field_class *scope_ctf_field_class_to_ir(struct ctx *ctx)
344 {
345 bt_field_class *ir_fc = NULL;
346 struct ctf_field_class *fc = NULL;
347
348 switch (ctx->scope) {
349 case CTF_SCOPE_PACKET_CONTEXT:
350 fc = ctx->sc->packet_context_fc;
351 break;
352 case CTF_SCOPE_EVENT_COMMON_CONTEXT:
353 fc = ctx->sc->event_common_context_fc;
354 break;
355 case CTF_SCOPE_EVENT_SPECIFIC_CONTEXT:
356 fc = ctx->ec->spec_context_fc;
357 break;
358 case CTF_SCOPE_EVENT_PAYLOAD:
359 fc = ctx->ec->payload_fc;
360 break;
361 default:
362 abort();
363 }
364
365 if (fc && ctf_field_class_struct_has_immediate_member_in_ir(
366 (void *) fc)) {
367 ir_fc = ctf_field_class_to_ir(ctx, fc);
368 }
369
370 return ir_fc;
371 }
372
373 static inline
374 struct ctf_field_class_int *borrow_named_int_field_class(
375 struct ctf_field_class_struct *struct_fc, const char *name)
376 {
377 struct ctf_named_field_class *named_fc = NULL;
378 struct ctf_field_class_int *int_fc = NULL;
379
380 if (!struct_fc) {
381 goto end;
382 }
383
384 named_fc = ctf_field_class_struct_borrow_member_by_name(struct_fc, name);
385 if (!named_fc) {
386 goto end;
387 }
388
389 if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT &&
390 named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
391 goto end;
392 }
393
394 int_fc = (void *) named_fc->fc;
395
396 end:
397 return int_fc;
398 }
399
400 static inline
401 void ctf_event_class_to_ir(struct ctx *ctx)
402 {
403 int ret;
404 bt_event_class *ir_ec = NULL;
405 bt_field_class *ir_fc;
406
407 BT_ASSERT(ctx->ec);
408
409 if (ctx->ec->is_translated) {
410 ir_ec = bt_stream_class_borrow_event_class_by_id(
411 ctx->ir_sc, ctx->ec->id);
412 BT_ASSERT(ir_ec);
413 goto end;
414 }
415
416 ir_ec = bt_event_class_create_with_id(ctx->ir_sc, ctx->ec->id);
417 BT_ASSERT(ir_ec);
418 bt_event_class_put_ref(ir_ec);
419 ctx->scope = CTF_SCOPE_EVENT_SPECIFIC_CONTEXT;
420 ir_fc = scope_ctf_field_class_to_ir(ctx);
421 if (ir_fc) {
422 ret = bt_event_class_set_specific_context_field_class(
423 ir_ec, ir_fc);
424 BT_ASSERT(ret == 0);
425 bt_field_class_put_ref(ir_fc);
426 }
427
428 ctx->scope = CTF_SCOPE_EVENT_PAYLOAD;
429 ir_fc = scope_ctf_field_class_to_ir(ctx);
430 if (ir_fc) {
431 ret = bt_event_class_set_payload_field_class(ir_ec,
432 ir_fc);
433 BT_ASSERT(ret == 0);
434 bt_field_class_put_ref(ir_fc);
435 }
436
437 if (ctx->ec->name->len > 0) {
438 ret = bt_event_class_set_name(ir_ec, ctx->ec->name->str);
439 BT_ASSERT(ret == 0);
440 }
441
442 if (ctx->ec->emf_uri->len > 0) {
443 ret = bt_event_class_set_emf_uri(ir_ec, ctx->ec->emf_uri->str);
444 BT_ASSERT(ret == 0);
445 }
446
447 if (ctx->ec->log_level != -1) {
448 bt_event_class_set_log_level(ir_ec, ctx->ec->log_level);
449 }
450
451 ctx->ec->is_translated = true;
452 ctx->ec->ir_ec = ir_ec;
453
454 end:
455 return;
456 }
457
458
459 static inline
460 void ctf_stream_class_to_ir(struct ctx *ctx)
461 {
462 int ret;
463 struct ctf_field_class_int *int_fc;
464 bt_field_class *ir_fc;
465
466 BT_ASSERT(ctx->sc);
467
468 if (ctx->sc->is_translated) {
469 ctx->ir_sc = bt_trace_class_borrow_stream_class_by_id(
470 ctx->ir_tc, ctx->sc->id);
471 BT_ASSERT(ctx->ir_sc);
472 goto end;
473 }
474
475 ctx->ir_sc = bt_stream_class_create_with_id(ctx->ir_tc, ctx->sc->id);
476 BT_ASSERT(ctx->ir_sc);
477 bt_stream_class_put_ref(ctx->ir_sc);
478 ctx->scope = CTF_SCOPE_PACKET_CONTEXT;
479 ir_fc = scope_ctf_field_class_to_ir(ctx);
480 if (ir_fc) {
481 ret = bt_stream_class_set_packet_context_field_class(
482 ctx->ir_sc, ir_fc);
483 BT_ASSERT(ret == 0);
484 bt_field_class_put_ref(ir_fc);
485 }
486
487 ctx->scope = CTF_SCOPE_EVENT_COMMON_CONTEXT;
488 ir_fc = scope_ctf_field_class_to_ir(ctx);
489 if (ir_fc) {
490 ret = bt_stream_class_set_event_common_context_field_class(
491 ctx->ir_sc, ir_fc);
492 BT_ASSERT(ret == 0);
493 bt_field_class_put_ref(ir_fc);
494 }
495
496 bt_stream_class_set_assigns_automatic_event_class_id(ctx->ir_sc,
497 BT_FALSE);
498 bt_stream_class_set_assigns_automatic_stream_id(ctx->ir_sc, BT_FALSE);
499
500 if (ctx->sc->default_clock_class) {
501 BT_ASSERT(ctx->sc->default_clock_class->ir_cc);
502 ret = bt_stream_class_set_default_clock_class(ctx->ir_sc,
503 ctx->sc->default_clock_class->ir_cc);
504 BT_ASSERT(ret == 0);
505 }
506
507 int_fc = borrow_named_int_field_class((void *) ctx->sc->packet_context_fc,
508 "events_discarded");
509 if (int_fc) {
510 if (int_fc->meaning == CTF_FIELD_CLASS_MEANING_DISC_EV_REC_COUNTER_SNAPSHOT) {
511 bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
512 ctx->ir_sc, BT_TRUE);
513 }
514 }
515
516 int_fc = borrow_named_int_field_class((void *) ctx->sc->packet_context_fc,
517 "packet_seq_num");
518 if (int_fc) {
519 if (int_fc->meaning == CTF_FIELD_CLASS_MEANING_PACKET_COUNTER_SNAPSHOT) {
520 bt_stream_class_set_packets_have_packet_counter_snapshot(
521 ctx->ir_sc, BT_TRUE);
522 }
523 }
524
525 int_fc = borrow_named_int_field_class((void *) ctx->sc->packet_context_fc,
526 "timestamp_begin");
527 if (int_fc) {
528 if (int_fc->meaning == CTF_FIELD_CLASS_MEANING_PACKET_BEGINNING_TIME) {
529 bt_stream_class_set_packets_have_default_beginning_clock_snapshot(
530 ctx->ir_sc, BT_TRUE);
531 }
532 }
533
534 int_fc = borrow_named_int_field_class((void *) ctx->sc->packet_context_fc,
535 "timestamp_end");
536 if (int_fc) {
537 if (int_fc->meaning == CTF_FIELD_CLASS_MEANING_PACKET_END_TIME) {
538 bt_stream_class_set_packets_have_default_end_clock_snapshot(
539 ctx->ir_sc, BT_TRUE);
540 }
541 }
542
543 ctx->sc->is_translated = true;
544 ctx->sc->ir_sc = ctx->ir_sc;
545
546 end:
547 return;
548 }
549
550 static inline
551 void ctf_clock_class_to_ir(bt_clock_class *ir_cc, struct ctf_clock_class *cc)
552 {
553 int ret;
554
555 if (strlen(cc->name->str) > 0) {
556 ret = bt_clock_class_set_name(ir_cc, cc->name->str);
557 BT_ASSERT(ret == 0);
558 }
559
560 if (strlen(cc->description->str) > 0) {
561 ret = bt_clock_class_set_description(ir_cc, cc->description->str);
562 BT_ASSERT(ret == 0);
563 }
564
565 bt_clock_class_set_frequency(ir_cc, cc->frequency);
566 bt_clock_class_set_precision(ir_cc, cc->precision);
567 bt_clock_class_set_offset(ir_cc, cc->offset_seconds, cc->offset_cycles);
568
569 if (cc->has_uuid) {
570 bt_clock_class_set_uuid(ir_cc, cc->uuid);
571 }
572
573 bt_clock_class_set_is_absolute(ir_cc, cc->is_absolute);
574 }
575
576 static inline
577 int ctf_trace_class_to_ir(struct ctx *ctx)
578 {
579 int ret = 0;
580 uint64_t i;
581
582 BT_ASSERT(ctx->tc);
583 BT_ASSERT(ctx->ir_tc);
584
585 if (ctx->tc->is_translated) {
586 goto end;
587 }
588
589 if (ctx->tc->is_uuid_set) {
590 bt_trace_class_set_uuid(ctx->ir_tc, ctx->tc->uuid);
591 }
592
593 for (i = 0; i < ctx->tc->env_entries->len; i++) {
594 struct ctf_trace_class_env_entry *env_entry =
595 ctf_trace_class_borrow_env_entry_by_index(ctx->tc, i);
596
597 switch (env_entry->type) {
598 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT:
599 ret = bt_trace_class_set_environment_entry_integer(
600 ctx->ir_tc, env_entry->name->str,
601 env_entry->value.i);
602 break;
603 case CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR:
604 ret = bt_trace_class_set_environment_entry_string(
605 ctx->ir_tc, env_entry->name->str,
606 env_entry->value.str->str);
607 break;
608 default:
609 abort();
610 }
611
612 if (ret) {
613 goto end;
614 }
615 }
616
617 for (i = 0; i < ctx->tc->clock_classes->len; i++) {
618 struct ctf_clock_class *cc = ctx->tc->clock_classes->pdata[i];
619
620 cc->ir_cc = bt_clock_class_create(ctx->ir_tc);
621 ctf_clock_class_to_ir(cc->ir_cc, cc);
622 }
623
624 bt_trace_class_set_assigns_automatic_stream_class_id(ctx->ir_tc,
625 BT_FALSE);
626 ctx->tc->is_translated = true;
627 ctx->tc->ir_tc = ctx->ir_tc;
628
629 end:
630 return ret;
631 }
632
633 BT_HIDDEN
634 int ctf_trace_class_translate(bt_trace_class *ir_tc,
635 struct ctf_trace_class *tc)
636 {
637 int ret = 0;
638 uint64_t i;
639 struct ctx ctx = { 0 };
640
641 ctx.tc = tc;
642 ctx.ir_tc = ir_tc;
643 ret = ctf_trace_class_to_ir(&ctx);
644 if (ret) {
645 goto end;
646 }
647
648 for (i = 0; i < tc->stream_classes->len; i++) {
649 uint64_t j;
650 ctx.sc = tc->stream_classes->pdata[i];
651
652 ctf_stream_class_to_ir(&ctx);
653
654 for (j = 0; j < ctx.sc->event_classes->len; j++) {
655 ctx.ec = ctx.sc->event_classes->pdata[j];
656
657 ctf_event_class_to_ir(&ctx);
658 ctx.ec = NULL;
659 }
660
661 ctx.sc = NULL;
662 }
663
664 end:
665 return ret;
666 }
This page took 0.046651 seconds and 4 git commands to generate.