1b4e9eb5f03822e202137ca170affd32cad84419
[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-internal.h>
33 #include <babeltrace/ctf-ir/event-types-internal.h>
34 #include <babeltrace/ctf-ir/event-fields-internal.h>
35 #include <babeltrace/ctf-writer/stream.h>
36 #include <babeltrace/ctf-ir/stream-class-internal.h>
37 #include <babeltrace/ctf-ir/visitor-internal.h>
38 #include <babeltrace/ctf-writer/functor-internal.h>
39 #include <babeltrace/ctf-ir/utils.h>
40 #include <babeltrace/ctf-ir/ref.h>
41 #include <babeltrace/ctf-ir/common-internal.h>
42 #include <babeltrace/compiler.h>
43 #include <babeltrace/align.h>
44
45 static
46 void bt_ctf_stream_class_destroy(struct bt_ref *ref);
47 static
48 int init_event_header(struct bt_ctf_stream_class *stream_class);
49 static
50 int init_packet_context(struct bt_ctf_stream_class *stream_class);
51
52 struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
53 {
54 int ret;
55 struct bt_ctf_stream_class *stream_class = NULL;
56
57 if (name && bt_ctf_validate_identifier(name)) {
58 goto error;
59 }
60
61 stream_class = g_new0(struct bt_ctf_stream_class, 1);
62 if (!stream_class) {
63 goto error;
64 }
65
66 stream_class->name = g_string_new(name);
67 stream_class->event_classes = g_ptr_array_new_with_free_func(
68 (GDestroyNotify)bt_ctf_event_class_put);
69 if (!stream_class->event_classes) {
70 goto error_destroy;
71 }
72
73 ret = init_event_header(stream_class);
74 if (ret) {
75 goto error_destroy;
76 }
77
78 ret = init_packet_context(stream_class);
79 if (ret) {
80 goto error_destroy;
81 }
82
83 bt_ctf_base_init(stream_class, bt_ctf_stream_class_destroy);
84 return stream_class;
85
86 error_destroy:
87 bt_ctf_stream_class_destroy(&stream_class->base.ref_count);
88 stream_class = NULL;
89 error:
90 return stream_class;
91 }
92
93 struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
94 struct bt_ctf_stream_class *stream_class)
95 {
96 struct bt_ctf_trace *trace = NULL;
97
98 if (!stream_class) {
99 goto end;
100 }
101
102 trace = stream_class->trace;
103 if (trace) {
104 bt_ctf_trace_get(trace);
105 }
106 end:
107 return trace;
108 }
109
110 const char *bt_ctf_stream_class_get_name(
111 struct bt_ctf_stream_class *stream_class)
112 {
113 const char *name = NULL;
114
115 if (!stream_class) {
116 goto end;
117 }
118
119 name = stream_class->name->str;
120 end:
121 return name;
122 }
123
124 int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
125 const char *name)
126 {
127 int ret = 0;
128
129 if (!stream_class || stream_class->frozen) {
130 ret = -1;
131 goto end;
132 }
133
134 g_string_assign(stream_class->name, name);
135 end:
136 return ret;
137 }
138
139 struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
140 struct bt_ctf_stream_class *stream_class)
141 {
142 struct bt_ctf_clock *clock = NULL;
143
144 if (!stream_class || !stream_class->clock) {
145 goto end;
146 }
147
148 clock = stream_class->clock;
149 bt_ctf_clock_get(clock);
150 end:
151 return clock;
152 }
153
154 int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
155 struct bt_ctf_clock *clock)
156 {
157 int ret = 0;
158 struct bt_ctf_field_type *timestamp_field = NULL;
159
160 if (!stream_class || !clock || stream_class->frozen) {
161 ret = -1;
162 goto end;
163 }
164
165 /*
166 * Look for a "timestamp" field in the stream class' event header type
167 * and map the stream's clock to that field if no current mapping is
168 * currently set.
169 */
170 timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
171 stream_class->event_header_type, "timestamp");
172 if (timestamp_field) {
173 struct bt_ctf_clock *mapped_clock;
174
175 mapped_clock = bt_ctf_field_type_integer_get_mapped_clock(
176 timestamp_field);
177 if (mapped_clock) {
178 bt_ctf_clock_put(mapped_clock);
179 goto end;
180 }
181
182 ret = bt_ctf_field_type_integer_set_mapped_clock(
183 timestamp_field, clock);
184 if (ret) {
185 goto end;
186 }
187 }
188
189 if (stream_class->clock) {
190 bt_ctf_clock_put(stream_class->clock);
191 }
192
193 stream_class->clock = clock;
194 bt_ctf_clock_get(clock);
195 end:
196 if (timestamp_field) {
197 bt_ctf_field_type_put(timestamp_field);
198 }
199 return ret;
200 }
201
202 int64_t bt_ctf_stream_class_get_id(struct bt_ctf_stream_class *stream_class)
203 {
204 int64_t ret;
205
206 if (!stream_class || !stream_class->id_set) {
207 ret = -1;
208 goto end;
209 }
210
211 ret = (int64_t) stream_class->id;
212 end:
213 return ret;
214 }
215
216 BT_HIDDEN
217 int _bt_ctf_stream_class_set_id(
218 struct bt_ctf_stream_class *stream_class, uint32_t id)
219 {
220 stream_class->id = id;
221 stream_class->id_set = 1;
222 return 0;
223 }
224
225 struct event_class_set_stream_id_data {
226 uint32_t stream_id;
227 int ret;
228 };
229
230 static
231 void event_class_set_stream_id(gpointer event_class, gpointer data)
232 {
233 struct event_class_set_stream_id_data *typed_data = data;
234
235 typed_data->ret |= bt_ctf_event_class_set_stream_id(event_class,
236 typed_data->stream_id);
237 }
238
239 BT_HIDDEN
240 int bt_ctf_stream_class_set_id_no_check(
241 struct bt_ctf_stream_class *stream_class, uint32_t id)
242 {
243 int ret = 0;
244 struct event_class_set_stream_id_data data =
245 { .stream_id = id, .ret = 0 };
246
247 /*
248 * Make sure all event classes have their "stream_id" attribute
249 * set to this value.
250 */
251 g_ptr_array_foreach(stream_class->event_classes,
252 event_class_set_stream_id, &data);
253 ret = data.ret;
254 if (ret) {
255 goto end;
256 }
257
258 ret = _bt_ctf_stream_class_set_id(stream_class, id);
259 if (ret) {
260 goto end;
261 }
262 end:
263 return ret;
264 }
265
266 int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
267 uint32_t id)
268 {
269 int ret = 0;
270
271 if (!stream_class || stream_class->frozen) {
272 ret = -1;
273 goto end;
274 }
275
276 ret = bt_ctf_stream_class_set_id_no_check(stream_class, id);
277 end:
278 return ret;
279 }
280
281 static
282 void event_class_exists(gpointer element, gpointer query)
283 {
284 struct bt_ctf_event_class *event_class_a = element;
285 struct search_query *search_query = query;
286 struct bt_ctf_event_class *event_class_b = search_query->value;
287 int64_t id_a, id_b;
288
289 if (search_query->value == element) {
290 search_query->found = 1;
291 goto end;
292 }
293
294 /*
295 * Two event classes cannot share the same name in a given
296 * stream class.
297 */
298 if (!strcmp(bt_ctf_event_class_get_name(event_class_a),
299 bt_ctf_event_class_get_name(event_class_b))) {
300 search_query->found = 1;
301 goto end;
302 }
303
304 /*
305 * Two event classes cannot share the same ID in a given
306 * stream class.
307 */
308 id_a = bt_ctf_event_class_get_id(event_class_a);
309 id_b = bt_ctf_event_class_get_id(event_class_b);
310
311 if (id_a < 0 || id_b < 0) {
312 /* at least one ID is not set: will be automatically set later */
313 goto end;
314 }
315
316 if (id_a == id_b) {
317 search_query->found = 1;
318 goto end;
319 }
320
321 end:
322 return;
323 }
324
325 int bt_ctf_stream_class_add_event_class(
326 struct bt_ctf_stream_class *stream_class,
327 struct bt_ctf_event_class *event_class)
328 {
329 int ret = 0;
330 int64_t event_id;
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 /*
347 * Resolve the event's sequence length and variant tags if the
348 * stream is already associated with a trace. Otherwise, this
349 * validation will be performed once the stream is registered
350 * to a trace.
351 */
352 if (stream_class->trace) {
353 ret = bt_ctf_event_class_resolve_types(event_class,
354 stream_class->trace, stream_class);
355 if (ret) {
356 goto end;
357 }
358 }
359
360 /* Only set an event id if none was explicitly set before */
361 event_id = bt_ctf_event_class_get_id(event_class);
362 if (event_id < 0) {
363 if (bt_ctf_event_class_set_id(event_class,
364 stream_class->next_event_id++)) {
365 ret = -1;
366 goto end;
367 }
368 }
369
370 ret = bt_ctf_event_class_set_stream_class(event_class, stream_class);
371 if (ret) {
372 goto end;
373 }
374
375 ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
376 if (ret) {
377 goto end;
378 }
379
380 bt_ctf_event_class_get(event_class);
381 g_ptr_array_add(stream_class->event_classes, event_class);
382 bt_ctf_event_class_freeze(event_class);
383
384 if (stream_class->byte_order) {
385 /*
386 * Only set native byte order if it has been initialized
387 * when the stream class was added to a trace.
388 *
389 * If not set here, this will be set when the stream
390 * classe will be added to a trace.
391 */
392 bt_ctf_event_class_set_native_byte_order(event_class,
393 stream_class->byte_order);
394 }
395 end:
396 return ret;
397 }
398
399 int bt_ctf_stream_class_get_event_class_count(
400 struct bt_ctf_stream_class *stream_class)
401 {
402 int ret;
403
404 if (!stream_class) {
405 ret = -1;
406 goto end;
407 }
408
409 ret = (int) stream_class->event_classes->len;
410 end:
411 return ret;
412 }
413
414 struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class(
415 struct bt_ctf_stream_class *stream_class, int index)
416 {
417 struct bt_ctf_event_class *event_class = NULL;
418
419 if (!stream_class || index < 0 ||
420 index >= stream_class->event_classes->len) {
421 goto end;
422 }
423
424 event_class = g_ptr_array_index(stream_class->event_classes, index);
425 bt_ctf_event_class_get(event_class);
426 end:
427 return event_class;
428 }
429
430 struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_name(
431 struct bt_ctf_stream_class *stream_class, const char *name)
432 {
433 size_t i;
434 struct bt_ctf_event_class *event_class = NULL;
435
436 if (!stream_class || !name) {
437 goto end;
438 }
439
440 for (i = 0; i < stream_class->event_classes->len; i++) {
441 struct bt_ctf_event_class *cur_event_class =
442 g_ptr_array_index(stream_class->event_classes, i);
443 const char *cur_event_class_name =
444 bt_ctf_event_class_get_name(cur_event_class);
445
446 if (!strcmp(name, cur_event_class_name)) {
447 event_class = cur_event_class;
448 bt_ctf_event_class_get(event_class);
449 goto end;
450 }
451 }
452 end:
453 return event_class;
454 }
455
456 struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
457 struct bt_ctf_stream_class *stream_class, uint32_t id)
458 {
459 size_t i;
460 struct bt_ctf_event_class *event_class = NULL;
461
462 if (!stream_class) {
463 goto end;
464 }
465
466 for (i = 0; i < stream_class->event_classes->len; i++) {
467 struct bt_ctf_event_class *current_event_class =
468 g_ptr_array_index(stream_class->event_classes, i);
469
470 if (bt_ctf_event_class_get_id(current_event_class) == id) {
471 event_class = current_event_class;
472 bt_ctf_event_class_get(event_class);
473 goto end;
474 }
475 }
476 end:
477 return event_class;
478 }
479
480 struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
481 struct bt_ctf_stream_class *stream_class)
482 {
483 struct bt_ctf_field_type *ret = NULL;
484
485 if (!stream_class) {
486 goto end;
487 }
488
489 assert(stream_class->packet_context_type);
490 bt_ctf_field_type_get(stream_class->packet_context_type);
491 ret = stream_class->packet_context_type;
492 end:
493 return ret;
494 }
495
496 int bt_ctf_stream_class_set_packet_context_type(
497 struct bt_ctf_stream_class *stream_class,
498 struct bt_ctf_field_type *packet_context_type)
499 {
500 int ret = 0;
501
502 if (!stream_class || !packet_context_type || stream_class->frozen) {
503 ret = -1;
504 goto end;
505 }
506
507 assert(stream_class->packet_context_type);
508 if (stream_class->packet_context_type == packet_context_type) {
509 goto end;
510 }
511 if (bt_ctf_field_type_get_type_id(packet_context_type) !=
512 CTF_TYPE_STRUCT) {
513 /* A packet context must be a structure */
514 ret = -1;
515 goto end;
516 }
517
518 bt_ctf_field_type_put(stream_class->packet_context_type);
519 bt_ctf_field_type_get(packet_context_type);
520 stream_class->packet_context_type = packet_context_type;
521 end:
522 return ret;
523 }
524
525 struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
526 struct bt_ctf_stream_class *stream_class)
527 {
528 struct bt_ctf_field_type *ret = NULL;
529
530 if (!stream_class || !stream_class->event_header_type) {
531 goto end;
532 }
533
534 assert(stream_class->event_header_type);
535 bt_ctf_field_type_get(stream_class->event_header_type);
536 ret = stream_class->event_header_type;
537 end:
538 return ret;
539 }
540
541 int bt_ctf_stream_class_set_event_header_type(
542 struct bt_ctf_stream_class *stream_class,
543 struct bt_ctf_field_type *event_header_type)
544 {
545 int ret = 0;
546
547 if (!stream_class || !event_header_type || stream_class->frozen) {
548 ret = -1;
549 goto end;
550 }
551
552 assert(stream_class->event_header_type);
553 if (stream_class->event_header_type == event_header_type) {
554 goto end;
555 }
556 if (bt_ctf_field_type_get_type_id(event_header_type) !=
557 CTF_TYPE_STRUCT) {
558 /* An event header must be a structure */
559 ret = -1;
560 goto end;
561 }
562
563 bt_ctf_field_type_put(stream_class->event_header_type);
564 bt_ctf_field_type_get(event_header_type);
565 stream_class->event_header_type = event_header_type;
566 end:
567 return ret;
568 }
569
570 struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
571 struct bt_ctf_stream_class *stream_class)
572 {
573 struct bt_ctf_field_type *ret = NULL;
574
575 if (!stream_class || !stream_class->event_context_type) {
576 goto end;
577 }
578
579 assert(stream_class->event_context_type);
580 bt_ctf_field_type_get(stream_class->event_context_type);
581 ret = stream_class->event_context_type;
582 end:
583 return ret;
584 }
585
586 int bt_ctf_stream_class_set_event_context_type(
587 struct bt_ctf_stream_class *stream_class,
588 struct bt_ctf_field_type *event_context_type)
589 {
590 int ret = 0;
591
592 if (!stream_class || !event_context_type || stream_class->frozen) {
593 ret = -1;
594 goto end;
595 }
596
597 if (bt_ctf_field_type_get_type_id(event_context_type) !=
598 CTF_TYPE_STRUCT) {
599 /* A packet context must be a structure */
600 ret = -1;
601 goto end;
602 }
603
604 bt_ctf_field_type_put(stream_class->event_context_type);
605 bt_ctf_field_type_get(event_context_type);
606 stream_class->event_context_type = event_context_type;
607 end:
608 return ret;
609 }
610
611 void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
612 {
613 bt_ctf_get(stream_class);
614 }
615
616 void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
617 {
618 bt_ctf_put(stream_class);
619 }
620
621 BT_HIDDEN
622 void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class)
623 {
624 if (!stream_class) {
625 return;
626 }
627
628 stream_class->frozen = 1;
629 bt_ctf_field_type_freeze(stream_class->event_header_type);
630 bt_ctf_field_type_freeze(stream_class->packet_context_type);
631 bt_ctf_field_type_freeze(stream_class->event_context_type);
632 bt_ctf_clock_freeze(stream_class->clock);
633 }
634
635 BT_HIDDEN
636 int bt_ctf_stream_class_set_byte_order(struct bt_ctf_stream_class *stream_class,
637 enum bt_ctf_byte_order byte_order)
638 {
639 int i, ret = 0;
640 int internal_byte_order;
641
642 /* Note that "NATIVE" means the trace's endianness, not the host's. */
643 if (!stream_class || byte_order <= BT_CTF_BYTE_ORDER_UNKNOWN ||
644 byte_order > BT_CTF_BYTE_ORDER_NETWORK) {
645 ret = -1;
646 goto end;
647 }
648
649 switch (byte_order) {
650 case BT_CTF_BYTE_ORDER_NETWORK:
651 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
652 internal_byte_order = BIG_ENDIAN;
653 break;
654 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
655 internal_byte_order = LITTLE_ENDIAN;
656 break;
657 default:
658 ret = -1;
659 goto end;
660 }
661
662 stream_class->byte_order = internal_byte_order;
663
664 /* Set native byte order to little or big endian */
665 bt_ctf_field_type_set_native_byte_order(
666 stream_class->event_header_type, stream_class->byte_order);
667 bt_ctf_field_type_set_native_byte_order(
668 stream_class->packet_context_type, stream_class->byte_order);
669 bt_ctf_field_type_set_native_byte_order(
670 stream_class->event_context_type, stream_class->byte_order);
671
672 /* Set all events' native byte order */
673 for (i = 0; i < stream_class->event_classes->len; i++) {
674 bt_ctf_event_class_set_native_byte_order(
675 g_ptr_array_index(stream_class->event_classes, i),
676 stream_class->byte_order);
677 bt_ctf_event_class_freeze(
678 g_ptr_array_index(stream_class->event_classes, i));
679 }
680 end:
681 return ret;
682 }
683
684 BT_HIDDEN
685 int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
686 struct metadata_context *context)
687 {
688 int64_t ret = 0;
689 size_t i;
690
691 g_string_assign(context->field_name, "");
692 context->current_indentation_level = 1;
693 if (!stream_class->id_set) {
694 ret = -1;
695 goto end;
696 }
697
698 g_string_append_printf(context->string,
699 "stream {\n\tid = %" PRIu32 ";\n\tevent.header := ",
700 stream_class->id);
701 ret = bt_ctf_field_type_serialize(stream_class->event_header_type,
702 context);
703 if (ret) {
704 goto end;
705 }
706
707 g_string_append(context->string, ";\n\n\tpacket.context := ");
708 ret = bt_ctf_field_type_serialize(stream_class->packet_context_type,
709 context);
710 if (ret) {
711 goto end;
712 }
713
714 if (stream_class->event_context_type) {
715 g_string_append(context->string, ";\n\n\tevent.context := ");
716 ret = bt_ctf_field_type_serialize(
717 stream_class->event_context_type, context);
718 if (ret) {
719 goto end;
720 }
721 }
722
723 g_string_append(context->string, ";\n};\n\n");
724 for (i = 0; i < stream_class->event_classes->len; i++) {
725 struct bt_ctf_event_class *event_class =
726 stream_class->event_classes->pdata[i];
727
728 ret = bt_ctf_event_class_serialize(event_class, context);
729 if (ret) {
730 goto end;
731 }
732 }
733 end:
734 context->current_indentation_level = 0;
735 return ret;
736 }
737
738 BT_HIDDEN
739 int bt_ctf_stream_class_set_trace(struct bt_ctf_stream_class *stream_class,
740 struct bt_ctf_trace *trace)
741 {
742 int ret = 0;
743
744 if (!stream_class) {
745 ret = -1;
746 goto end;
747 }
748
749 if (stream_class->trace && trace) {
750 /* Already attached to a trace */
751 ret = -1;
752 goto end;
753 }
754
755 stream_class->trace = trace;
756 end:
757 return ret;
758 }
759
760 static
761 void bt_ctf_stream_class_destroy(struct bt_ref *ref)
762 {
763 struct bt_ctf_stream_class *stream_class;
764 struct bt_ctf_base *base;
765
766 if (!ref) {
767 return;
768 }
769
770 base = container_of(ref, struct bt_ctf_base, ref_count);
771 stream_class = container_of(base, struct bt_ctf_stream_class, base);
772 bt_ctf_clock_put(stream_class->clock);
773
774 if (stream_class->event_classes) {
775 size_t i;
776
777 /* Unregister this stream class from the event classes */
778 for (i = 0; i < stream_class->event_classes->len; i++) {
779 struct bt_ctf_event_class *event_class =
780 g_ptr_array_index(stream_class->event_classes,
781 i);
782
783 bt_ctf_event_class_set_stream_class(event_class, NULL);
784 }
785
786 g_ptr_array_free(stream_class->event_classes, TRUE);
787 }
788
789 if (stream_class->name) {
790 g_string_free(stream_class->name, TRUE);
791 }
792
793 bt_ctf_field_type_put(stream_class->event_header_type);
794 bt_ctf_field_type_put(stream_class->packet_context_type);
795 if (stream_class->event_context_type) {
796 bt_ctf_field_type_put(stream_class->event_context_type);
797 }
798 g_free(stream_class);
799 }
800
801 static
802 int init_event_header(struct bt_ctf_stream_class *stream_class)
803 {
804 int ret = 0;
805 struct bt_ctf_field_type *event_header_type =
806 bt_ctf_field_type_structure_create();
807 struct bt_ctf_field_type *_uint32_t =
808 get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
809 struct bt_ctf_field_type *_uint64_t =
810 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
811
812 if (!event_header_type) {
813 ret = -1;
814 goto end;
815 }
816
817 ret = bt_ctf_field_type_structure_add_field(event_header_type,
818 _uint32_t, "id");
819 if (ret) {
820 goto end;
821 }
822
823 ret = bt_ctf_field_type_structure_add_field(event_header_type,
824 _uint64_t, "timestamp");
825 if (ret) {
826 goto end;
827 }
828
829 if (stream_class->event_header_type) {
830 bt_ctf_field_type_put(stream_class->event_header_type);
831 }
832 stream_class->event_header_type = event_header_type;
833 end:
834 if (ret) {
835 bt_ctf_field_type_put(event_header_type);
836 }
837
838 bt_ctf_field_type_put(_uint32_t);
839 bt_ctf_field_type_put(_uint64_t);
840 return ret;
841 }
842
843 static
844 int init_packet_context(struct bt_ctf_stream_class *stream_class)
845 {
846 int ret = 0;
847 struct bt_ctf_field_type *packet_context_type =
848 bt_ctf_field_type_structure_create();
849 struct bt_ctf_field_type *_uint64_t =
850 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
851
852 if (!packet_context_type) {
853 ret = -1;
854 goto end;
855 }
856
857 /*
858 * We create a stream packet context as proposed in the CTF
859 * specification.
860 */
861 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
862 _uint64_t, "timestamp_begin");
863 if (ret) {
864 goto end;
865 }
866
867 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
868 _uint64_t, "timestamp_end");
869 if (ret) {
870 goto end;
871 }
872
873 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
874 _uint64_t, "content_size");
875 if (ret) {
876 goto end;
877 }
878
879 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
880 _uint64_t, "packet_size");
881 if (ret) {
882 goto end;
883 }
884
885 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
886 _uint64_t, "events_discarded");
887 if (ret) {
888 goto end;
889 }
890
891 if (stream_class->packet_context_type) {
892 bt_ctf_field_type_put(stream_class->packet_context_type);
893 }
894 stream_class->packet_context_type = packet_context_type;
895 end:
896 if (ret) {
897 bt_ctf_field_type_put(packet_context_type);
898 goto end;
899 }
900
901 bt_ctf_field_type_put(_uint64_t);
902 return ret;
903 }
This page took 0.049215 seconds and 3 git commands to generate.