Backport the CTF-IR interface
[babeltrace.git] / formats / ctf / ir / stream-class.c
1 /*
2 * stream-class.c
3 *
4 * Babeltrace CTF IR - Stream Class
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29 #include <babeltrace/ctf-writer/clock.h>
30 #include <babeltrace/ctf-ir/clock-internal.h>
31 #include <babeltrace/ctf-writer/event.h>
32 #include <babeltrace/ctf-ir/event-class-internal.h>
33 #include <babeltrace/ctf-ir/event-internal.h>
34 #include <babeltrace/ctf-ir/field-types-internal.h>
35 #include <babeltrace/ctf-ir/fields-internal.h>
36 #include <babeltrace/ctf-writer/stream.h>
37 #include <babeltrace/ctf-ir/stream-class-internal.h>
38 #include <babeltrace/ctf-ir/validation-internal.h>
39 #include <babeltrace/ctf-writer/functor-internal.h>
40 #include <babeltrace/ctf-ir/utils.h>
41 #include <babeltrace/ref.h>
42 #include <babeltrace/compiler.h>
43 #include <babeltrace/align.h>
44 #include <babeltrace/endian.h>
45
46 static
47 void bt_ctf_stream_class_destroy(struct bt_object *obj);
48 static
49 int init_event_header(struct bt_ctf_stream_class *stream_class);
50 static
51 int init_packet_context(struct bt_ctf_stream_class *stream_class);
52
53 struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
54 {
55 int ret;
56 struct bt_ctf_stream_class *stream_class = NULL;
57
58 if (name && bt_ctf_validate_identifier(name)) {
59 goto error;
60 }
61
62 stream_class = g_new0(struct bt_ctf_stream_class, 1);
63 if (!stream_class) {
64 goto error;
65 }
66
67 stream_class->name = g_string_new(name);
68 stream_class->event_classes = g_ptr_array_new_with_free_func(
69 (GDestroyNotify) bt_object_release);
70 if (!stream_class->event_classes) {
71 goto error;
72 }
73
74 ret = init_event_header(stream_class);
75 if (ret) {
76 goto error;
77 }
78
79 ret = init_packet_context(stream_class);
80 if (ret) {
81 goto error;
82 }
83
84 bt_object_init(stream_class, bt_ctf_stream_class_destroy);
85 return stream_class;
86
87 error:
88 BT_PUT(stream_class);
89 return stream_class;
90 }
91
92 struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
93 struct bt_ctf_stream_class *stream_class)
94 {
95 return (struct bt_ctf_trace *) bt_object_get_parent(
96 stream_class);
97 }
98
99 const char *bt_ctf_stream_class_get_name(
100 struct bt_ctf_stream_class *stream_class)
101 {
102 const char *name = NULL;
103
104 if (!stream_class) {
105 goto end;
106 }
107
108 name = stream_class->name->str;
109 end:
110 return name;
111 }
112
113 int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
114 const char *name)
115 {
116 int ret = 0;
117
118 if (!stream_class || stream_class->frozen) {
119 ret = -1;
120 goto end;
121 }
122
123 g_string_assign(stream_class->name, name);
124 end:
125 return ret;
126 }
127
128 struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
129 struct bt_ctf_stream_class *stream_class)
130 {
131 struct bt_ctf_clock *clock = NULL;
132
133 if (!stream_class || !stream_class->clock) {
134 goto end;
135 }
136
137 clock = stream_class->clock;
138 bt_get(clock);
139 end:
140 return clock;
141 }
142
143 int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
144 struct bt_ctf_clock *clock)
145 {
146 int ret = 0;
147 struct bt_ctf_field_type *timestamp_field = NULL;
148
149 if (!stream_class || !clock || stream_class->frozen) {
150 ret = -1;
151 goto end;
152 }
153
154 /*
155 * Look for a "timestamp" field in the stream class' event header type
156 * and map the stream's clock to that field if no current mapping is
157 * currently set.
158 */
159 timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
160 stream_class->event_header_type, "timestamp");
161 if (timestamp_field) {
162 struct bt_ctf_clock *mapped_clock;
163
164 mapped_clock = bt_ctf_field_type_integer_get_mapped_clock(
165 timestamp_field);
166 if (mapped_clock) {
167 bt_put(mapped_clock);
168 goto end;
169 }
170
171 ret = bt_ctf_field_type_integer_set_mapped_clock(
172 timestamp_field, clock);
173 if (ret) {
174 goto end;
175 }
176 }
177
178 if (stream_class->clock) {
179 bt_put(stream_class->clock);
180 }
181
182 stream_class->clock = clock;
183 bt_get(clock);
184 end:
185 if (timestamp_field) {
186 bt_put(timestamp_field);
187 }
188 return ret;
189 }
190
191 int64_t bt_ctf_stream_class_get_id(struct bt_ctf_stream_class *stream_class)
192 {
193 int64_t ret;
194
195 if (!stream_class || !stream_class->id_set) {
196 ret = -1;
197 goto end;
198 }
199
200 ret = (int64_t) stream_class->id;
201 end:
202 return ret;
203 }
204
205 BT_HIDDEN
206 int _bt_ctf_stream_class_set_id(
207 struct bt_ctf_stream_class *stream_class, uint32_t id)
208 {
209 stream_class->id = id;
210 stream_class->id_set = 1;
211 return 0;
212 }
213
214 struct event_class_set_stream_id_data {
215 uint32_t stream_id;
216 int ret;
217 };
218
219 static
220 void event_class_set_stream_id(gpointer event_class, gpointer data)
221 {
222 struct event_class_set_stream_id_data *typed_data = data;
223
224 typed_data->ret |= bt_ctf_event_class_set_stream_id(event_class,
225 typed_data->stream_id);
226 }
227
228 BT_HIDDEN
229 int bt_ctf_stream_class_set_id_no_check(
230 struct bt_ctf_stream_class *stream_class, uint32_t id)
231 {
232 int ret = 0;
233 struct event_class_set_stream_id_data data =
234 { .stream_id = id, .ret = 0 };
235
236 /*
237 * Make sure all event classes have their "stream_id" attribute
238 * set to this value.
239 */
240 g_ptr_array_foreach(stream_class->event_classes,
241 event_class_set_stream_id, &data);
242 ret = data.ret;
243 if (ret) {
244 goto end;
245 }
246
247 ret = _bt_ctf_stream_class_set_id(stream_class, id);
248 if (ret) {
249 goto end;
250 }
251 end:
252 return ret;
253 }
254
255 int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
256 uint32_t id)
257 {
258 int ret = 0;
259
260 if (!stream_class || stream_class->frozen) {
261 ret = -1;
262 goto end;
263 }
264
265 ret = bt_ctf_stream_class_set_id_no_check(stream_class, id);
266 end:
267 return ret;
268 }
269
270 static
271 void event_class_exists(gpointer element, gpointer query)
272 {
273 struct bt_ctf_event_class *event_class_a = element;
274 struct search_query *search_query = query;
275 struct bt_ctf_event_class *event_class_b = search_query->value;
276 int64_t id_a, id_b;
277
278 if (search_query->value == element) {
279 search_query->found = 1;
280 goto end;
281 }
282
283 /*
284 * Two event classes cannot share the same name in a given
285 * stream class.
286 */
287 if (!strcmp(bt_ctf_event_class_get_name(event_class_a),
288 bt_ctf_event_class_get_name(event_class_b))) {
289 search_query->found = 1;
290 goto end;
291 }
292
293 /*
294 * Two event classes cannot share the same ID in a given
295 * stream class.
296 */
297 id_a = bt_ctf_event_class_get_id(event_class_a);
298 id_b = bt_ctf_event_class_get_id(event_class_b);
299
300 if (id_a < 0 || id_b < 0) {
301 /* at least one ID is not set: will be automatically set later */
302 goto end;
303 }
304
305 if (id_a == id_b) {
306 search_query->found = 1;
307 goto end;
308 }
309
310 end:
311 return;
312 }
313
314 int bt_ctf_stream_class_add_event_class(
315 struct bt_ctf_stream_class *stream_class,
316 struct bt_ctf_event_class *event_class)
317 {
318 int ret = 0;
319 int64_t event_id;
320 struct bt_ctf_trace *trace = NULL;
321 struct bt_ctf_stream_class *old_stream_class = NULL;
322 struct bt_ctf_validation_output validation_output = { 0 };
323 struct bt_ctf_field_type *packet_header_type = NULL;
324 struct bt_ctf_field_type *packet_context_type = NULL;
325 struct bt_ctf_field_type *event_header_type = NULL;
326 struct bt_ctf_field_type *stream_event_ctx_type = NULL;
327 struct bt_ctf_field_type *event_context_type = NULL;
328 struct bt_ctf_field_type *event_payload_type = NULL;
329 const enum bt_ctf_validation_flag validation_flags =
330 BT_CTF_VALIDATION_FLAG_EVENT;
331
332 if (!stream_class || !event_class) {
333 ret = -1;
334 goto end;
335 }
336
337 /* Check for duplicate event classes */
338 struct search_query query = { .value = event_class, .found = 0 };
339 g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
340 &query);
341 if (query.found) {
342 ret = -1;
343 goto end;
344 }
345
346 old_stream_class = bt_ctf_event_class_get_stream_class(event_class);
347 if (old_stream_class) {
348 /* Event class is already associated to a stream class. */
349 ret = -1;
350 goto end;
351 }
352
353 trace = bt_ctf_stream_class_get_trace(stream_class);
354 if (trace) {
355 /*
356 * If the stream class is associated with a trace, then
357 * both those objects are frozen. Also, this event class
358 * is about to be frozen.
359 *
360 * Therefore the event class must be validated here.
361 * The trace and stream class should be valid at this
362 * point.
363 */
364 assert(trace->valid);
365 assert(stream_class->valid);
366 packet_header_type =
367 bt_ctf_trace_get_packet_header_type(trace);
368 packet_context_type =
369 bt_ctf_stream_class_get_packet_context_type(
370 stream_class);
371 event_header_type =
372 bt_ctf_stream_class_get_event_header_type(stream_class);
373 stream_event_ctx_type =
374 bt_ctf_stream_class_get_event_context_type(
375 stream_class);
376 event_context_type =
377 bt_ctf_event_class_get_context_type(event_class);
378 event_payload_type =
379 bt_ctf_event_class_get_payload_type(event_class);
380 ret = bt_ctf_validate_class_types(
381 trace->environment, packet_header_type,
382 packet_context_type, event_header_type,
383 stream_event_ctx_type, event_context_type,
384 event_payload_type, trace->valid,
385 stream_class->valid, event_class->valid,
386 &validation_output, validation_flags);
387 BT_PUT(packet_header_type);
388 BT_PUT(packet_context_type);
389 BT_PUT(event_header_type);
390 BT_PUT(stream_event_ctx_type);
391 BT_PUT(event_context_type);
392 BT_PUT(event_payload_type);
393
394 if (ret) {
395 /*
396 * This means something went wrong during the
397 * validation process, not that the objects are
398 * invalid.
399 */
400 goto end;
401 }
402
403 if ((validation_output.valid_flags & validation_flags) !=
404 validation_flags) {
405 /* Invalid event class */
406 ret = -1;
407 goto end;
408 }
409 }
410
411 /* Only set an event ID if none was explicitly set before */
412 event_id = bt_ctf_event_class_get_id(event_class);
413 if (event_id < 0) {
414 if (bt_ctf_event_class_set_id(event_class,
415 stream_class->next_event_id++)) {
416 ret = -1;
417 goto end;
418 }
419 }
420
421 ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
422 if (ret) {
423 goto end;
424 }
425
426 bt_object_set_parent(event_class, stream_class);
427
428 if (trace) {
429 /*
430 * At this point we know that the function will be
431 * successful. Therefore we can replace the event
432 * class's field types with what's in the validation
433 * output structure and mark this event class as valid.
434 */
435 bt_ctf_validation_replace_types(NULL, NULL, event_class,
436 &validation_output, validation_flags);
437 event_class->valid = 1;
438
439 /*
440 * Put what was not moved in
441 * bt_ctf_validation_replace_types().
442 */
443 bt_ctf_validation_output_put_types(&validation_output);
444 }
445
446 /* Add to the event classes of the stream class */
447 g_ptr_array_add(stream_class->event_classes, event_class);
448
449 /* Freeze the event class */
450 bt_ctf_event_class_freeze(event_class);
451
452 if (stream_class->byte_order) {
453 /*
454 * Only set native byte order if it has been initialized
455 * when the stream class was added to a trace.
456 *
457 * If not set here, this will be set when the stream
458 * class is added to a trace.
459 */
460 bt_ctf_event_class_set_native_byte_order(event_class,
461 stream_class->byte_order);
462 }
463
464 end:
465 BT_PUT(trace);
466 BT_PUT(old_stream_class);
467 bt_ctf_validation_output_put_types(&validation_output);
468 assert(!packet_header_type);
469 assert(!packet_context_type);
470 assert(!event_header_type);
471 assert(!stream_event_ctx_type);
472 assert(!event_context_type);
473 assert(!event_payload_type);
474
475 return ret;
476 }
477
478 int bt_ctf_stream_class_get_event_class_count(
479 struct bt_ctf_stream_class *stream_class)
480 {
481 int ret;
482
483 if (!stream_class) {
484 ret = -1;
485 goto end;
486 }
487
488 ret = (int) stream_class->event_classes->len;
489 end:
490 return ret;
491 }
492
493 struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class(
494 struct bt_ctf_stream_class *stream_class, int index)
495 {
496 struct bt_ctf_event_class *event_class = NULL;
497
498 if (!stream_class || index < 0 ||
499 index >= stream_class->event_classes->len) {
500 goto end;
501 }
502
503 event_class = g_ptr_array_index(stream_class->event_classes, index);
504 bt_get(event_class);
505 end:
506 return event_class;
507 }
508
509 struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_name(
510 struct bt_ctf_stream_class *stream_class, const char *name)
511 {
512 size_t i;
513 struct bt_ctf_event_class *event_class = NULL;
514
515 if (!stream_class || !name) {
516 goto end;
517 }
518
519 for (i = 0; i < stream_class->event_classes->len; i++) {
520 struct bt_ctf_event_class *cur_event_class =
521 g_ptr_array_index(stream_class->event_classes, i);
522 const char *cur_event_class_name =
523 bt_ctf_event_class_get_name(cur_event_class);
524
525 if (!strcmp(name, cur_event_class_name)) {
526 event_class = cur_event_class;
527 bt_get(event_class);
528 goto end;
529 }
530 }
531 end:
532 return event_class;
533 }
534
535 struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
536 struct bt_ctf_stream_class *stream_class, uint32_t id)
537 {
538 size_t i;
539 struct bt_ctf_event_class *event_class = NULL;
540
541 if (!stream_class) {
542 goto end;
543 }
544
545 for (i = 0; i < stream_class->event_classes->len; i++) {
546 struct bt_ctf_event_class *current_event_class =
547 g_ptr_array_index(stream_class->event_classes, i);
548
549 if (bt_ctf_event_class_get_id(current_event_class) == id) {
550 event_class = current_event_class;
551 bt_get(event_class);
552 goto end;
553 }
554 }
555 end:
556 return event_class;
557 }
558
559 struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
560 struct bt_ctf_stream_class *stream_class)
561 {
562 struct bt_ctf_field_type *ret = NULL;
563
564 if (!stream_class) {
565 goto end;
566 }
567
568 assert(stream_class->packet_context_type);
569 bt_get(stream_class->packet_context_type);
570 ret = stream_class->packet_context_type;
571 end:
572 return ret;
573 }
574
575 int bt_ctf_stream_class_set_packet_context_type(
576 struct bt_ctf_stream_class *stream_class,
577 struct bt_ctf_field_type *packet_context_type)
578 {
579 int ret = 0;
580
581 if (!stream_class || !packet_context_type || stream_class->frozen) {
582 ret = -1;
583 goto end;
584 }
585
586 assert(stream_class->packet_context_type);
587 if (stream_class->packet_context_type == packet_context_type) {
588 goto end;
589 }
590 if (bt_ctf_field_type_get_type_id(packet_context_type) !=
591 BT_CTF_TYPE_ID_STRUCT) {
592 /* A packet context must be a structure */
593 ret = -1;
594 goto end;
595 }
596
597 bt_put(stream_class->packet_context_type);
598 bt_get(packet_context_type);
599 stream_class->packet_context_type = packet_context_type;
600 end:
601 return ret;
602 }
603
604 struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
605 struct bt_ctf_stream_class *stream_class)
606 {
607 struct bt_ctf_field_type *ret = NULL;
608
609 if (!stream_class || !stream_class->event_header_type) {
610 goto end;
611 }
612
613 assert(stream_class->event_header_type);
614 bt_get(stream_class->event_header_type);
615 ret = stream_class->event_header_type;
616 end:
617 return ret;
618 }
619
620 int bt_ctf_stream_class_set_event_header_type(
621 struct bt_ctf_stream_class *stream_class,
622 struct bt_ctf_field_type *event_header_type)
623 {
624 int ret = 0;
625
626 if (!stream_class || !event_header_type || stream_class->frozen) {
627 ret = -1;
628 goto end;
629 }
630
631 assert(stream_class->event_header_type);
632 if (stream_class->event_header_type == event_header_type) {
633 goto end;
634 }
635 if (bt_ctf_field_type_get_type_id(event_header_type) !=
636 BT_CTF_TYPE_ID_STRUCT) {
637 /* An event header must be a structure */
638 ret = -1;
639 goto end;
640 }
641
642 bt_put(stream_class->event_header_type);
643 bt_get(event_header_type);
644 stream_class->event_header_type = event_header_type;
645 end:
646 return ret;
647 }
648
649 struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
650 struct bt_ctf_stream_class *stream_class)
651 {
652 struct bt_ctf_field_type *ret = NULL;
653
654 if (!stream_class || !stream_class->event_context_type) {
655 goto end;
656 }
657
658 assert(stream_class->event_context_type);
659 bt_get(stream_class->event_context_type);
660 ret = stream_class->event_context_type;
661 end:
662 return ret;
663 }
664
665 int bt_ctf_stream_class_set_event_context_type(
666 struct bt_ctf_stream_class *stream_class,
667 struct bt_ctf_field_type *event_context_type)
668 {
669 int ret = 0;
670
671 if (!stream_class || !event_context_type || stream_class->frozen) {
672 ret = -1;
673 goto end;
674 }
675
676 if (bt_ctf_field_type_get_type_id(event_context_type) !=
677 BT_CTF_TYPE_ID_STRUCT) {
678 /* A packet context must be a structure */
679 ret = -1;
680 goto end;
681 }
682
683 bt_put(stream_class->event_context_type);
684 bt_get(event_context_type);
685 stream_class->event_context_type = event_context_type;
686 end:
687 return ret;
688 }
689
690 void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
691 {
692 bt_get(stream_class);
693 }
694
695 void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
696 {
697 bt_put(stream_class);
698 }
699
700 BT_HIDDEN
701 void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class)
702 {
703 if (!stream_class) {
704 return;
705 }
706
707 stream_class->frozen = 1;
708 bt_ctf_field_type_freeze(stream_class->event_header_type);
709 bt_ctf_field_type_freeze(stream_class->packet_context_type);
710 bt_ctf_field_type_freeze(stream_class->event_context_type);
711 bt_ctf_clock_freeze(stream_class->clock);
712 }
713
714 BT_HIDDEN
715 void bt_ctf_stream_class_set_byte_order(
716 struct bt_ctf_stream_class *stream_class, int byte_order)
717 {
718 int i;
719
720 assert(stream_class);
721 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
722 stream_class->byte_order = byte_order;
723
724 /* Set native byte order to little or big endian */
725 bt_ctf_field_type_set_native_byte_order(
726 stream_class->event_header_type, byte_order);
727 bt_ctf_field_type_set_native_byte_order(
728 stream_class->packet_context_type, byte_order);
729 bt_ctf_field_type_set_native_byte_order(
730 stream_class->event_context_type, byte_order);
731
732 /* Set all events' native byte order */
733 for (i = 0; i < stream_class->event_classes->len; i++) {
734 struct bt_ctf_event_class *event_class =
735 g_ptr_array_index(stream_class->event_classes, i);
736
737 bt_ctf_event_class_set_native_byte_order(event_class,
738 byte_order);
739 }
740 }
741
742 BT_HIDDEN
743 int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
744 struct metadata_context *context)
745 {
746 int64_t ret = 0;
747 size_t i;
748
749 g_string_assign(context->field_name, "");
750 context->current_indentation_level = 1;
751 if (!stream_class->id_set) {
752 ret = -1;
753 goto end;
754 }
755
756 g_string_append_printf(context->string,
757 "stream {\n\tid = %" PRIu32 ";\n\tevent.header := ",
758 stream_class->id);
759 ret = bt_ctf_field_type_serialize(stream_class->event_header_type,
760 context);
761 if (ret) {
762 goto end;
763 }
764
765 g_string_append(context->string, ";\n\n\tpacket.context := ");
766 ret = bt_ctf_field_type_serialize(stream_class->packet_context_type,
767 context);
768 if (ret) {
769 goto end;
770 }
771
772 if (stream_class->event_context_type) {
773 g_string_append(context->string, ";\n\n\tevent.context := ");
774 ret = bt_ctf_field_type_serialize(
775 stream_class->event_context_type, context);
776 if (ret) {
777 goto end;
778 }
779 }
780
781 g_string_append(context->string, ";\n};\n\n");
782 for (i = 0; i < stream_class->event_classes->len; i++) {
783 struct bt_ctf_event_class *event_class =
784 stream_class->event_classes->pdata[i];
785
786 ret = bt_ctf_event_class_serialize(event_class, context);
787 if (ret) {
788 goto end;
789 }
790 }
791 end:
792 context->current_indentation_level = 0;
793 return ret;
794 }
795
796 static
797 void bt_ctf_stream_class_destroy(struct bt_object *obj)
798 {
799 struct bt_ctf_stream_class *stream_class;
800
801 stream_class = container_of(obj, struct bt_ctf_stream_class, base);
802 bt_put(stream_class->clock);
803
804 if (stream_class->event_classes) {
805 g_ptr_array_free(stream_class->event_classes, TRUE);
806 }
807
808 if (stream_class->name) {
809 g_string_free(stream_class->name, TRUE);
810 }
811
812 bt_put(stream_class->event_header_type);
813 bt_put(stream_class->packet_context_type);
814 bt_put(stream_class->event_context_type);
815 g_free(stream_class);
816 }
817
818 static
819 int init_event_header(struct bt_ctf_stream_class *stream_class)
820 {
821 int ret = 0;
822 struct bt_ctf_field_type *event_header_type =
823 bt_ctf_field_type_structure_create();
824 struct bt_ctf_field_type *_uint32_t =
825 get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
826 struct bt_ctf_field_type *_uint64_t =
827 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
828
829 if (!event_header_type) {
830 ret = -1;
831 goto end;
832 }
833
834 ret = bt_ctf_field_type_structure_add_field(event_header_type,
835 _uint32_t, "id");
836 if (ret) {
837 goto end;
838 }
839
840 ret = bt_ctf_field_type_structure_add_field(event_header_type,
841 _uint64_t, "timestamp");
842 if (ret) {
843 goto end;
844 }
845
846 if (stream_class->event_header_type) {
847 bt_put(stream_class->event_header_type);
848 }
849 stream_class->event_header_type = event_header_type;
850 end:
851 if (ret) {
852 bt_put(event_header_type);
853 }
854
855 bt_put(_uint32_t);
856 bt_put(_uint64_t);
857 return ret;
858 }
859
860 static
861 int init_packet_context(struct bt_ctf_stream_class *stream_class)
862 {
863 int ret = 0;
864 struct bt_ctf_field_type *packet_context_type =
865 bt_ctf_field_type_structure_create();
866 struct bt_ctf_field_type *_uint64_t =
867 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
868
869 if (!packet_context_type) {
870 ret = -1;
871 goto end;
872 }
873
874 /*
875 * We create a stream packet context as proposed in the CTF
876 * specification.
877 */
878 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
879 _uint64_t, "timestamp_begin");
880 if (ret) {
881 goto end;
882 }
883
884 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
885 _uint64_t, "timestamp_end");
886 if (ret) {
887 goto end;
888 }
889
890 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
891 _uint64_t, "content_size");
892 if (ret) {
893 goto end;
894 }
895
896 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
897 _uint64_t, "packet_size");
898 if (ret) {
899 goto end;
900 }
901
902 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
903 _uint64_t, "events_discarded");
904 if (ret) {
905 goto end;
906 }
907
908 bt_put(stream_class->packet_context_type);
909 stream_class->packet_context_type = packet_context_type;
910 end:
911 if (ret) {
912 bt_put(packet_context_type);
913 goto end;
914 }
915
916 bt_put(_uint64_t);
917 return ret;
918 }
This page took 0.048538 seconds and 4 git commands to generate.