Add trace moficiation notification handler interface
[babeltrace.git] / formats / ctf / ir / stream-class.c
CommitLineData
11b0cdc8 1/*
3f043b05 2 * stream-class.c
11b0cdc8 3 *
d2dc44b6 4 * Babeltrace CTF IR - Stream Class
11b0cdc8 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
11b0cdc8
JG
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>
272df73e 32#include <babeltrace/ctf-ir/event-class-internal.h>
11b0cdc8 33#include <babeltrace/ctf-ir/event-internal.h>
2e33ac5a
PP
34#include <babeltrace/ctf-ir/field-types-internal.h>
35#include <babeltrace/ctf-ir/fields-internal.h>
11b0cdc8
JG
36#include <babeltrace/ctf-writer/stream.h>
37#include <babeltrace/ctf-ir/stream-class-internal.h>
09840de5 38#include <babeltrace/ctf-ir/validation-internal.h>
11b0cdc8 39#include <babeltrace/ctf-writer/functor-internal.h>
654c1444 40#include <babeltrace/ctf-ir/utils.h>
83509119 41#include <babeltrace/ref.h>
11b0cdc8
JG
42#include <babeltrace/compiler.h>
43#include <babeltrace/align.h>
a0b720b2 44#include <babeltrace/endian.h>
11b0cdc8
JG
45
46static
83509119 47void bt_ctf_stream_class_destroy(struct bt_object *obj);
11b0cdc8 48static
662e778c 49int init_event_header(struct bt_ctf_stream_class *stream_class);
11b0cdc8 50static
662e778c 51int init_packet_context(struct bt_ctf_stream_class *stream_class);
11b0cdc8
JG
52
53struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
54{
12c8a1a3 55 int ret;
11b0cdc8
JG
56 struct bt_ctf_stream_class *stream_class = NULL;
57
3ea33115 58 if (name && bt_ctf_validate_identifier(name)) {
11b0cdc8
JG
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(
e6a8e8e4 69 (GDestroyNotify) bt_object_release);
11b0cdc8 70 if (!stream_class->event_classes) {
83509119 71 goto error;
11b0cdc8
JG
72 }
73
662e778c
JG
74 ret = init_event_header(stream_class);
75 if (ret) {
83509119 76 goto error;
662e778c
JG
77 }
78
79 ret = init_packet_context(stream_class);
12c8a1a3 80 if (ret) {
83509119 81 goto error;
12c8a1a3
JG
82 }
83
83509119 84 bt_object_init(stream_class, bt_ctf_stream_class_destroy);
11b0cdc8
JG
85 return stream_class;
86
11b0cdc8 87error:
83509119 88 BT_PUT(stream_class);
11b0cdc8
JG
89 return stream_class;
90}
91
142c5610
JG
92struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
93 struct bt_ctf_stream_class *stream_class)
94{
e6a8e8e4
JG
95 return (struct bt_ctf_trace *) bt_object_get_parent(
96 stream_class);
142c5610
JG
97}
98
69dc4535
JG
99const 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;
109end:
110 return name;
111}
112
3ea33115
JG
113int 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);
124end:
125 return ret;
126}
127
2f100782
JG
128struct 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;
83509119 138 bt_get(clock);
2f100782
JG
139end:
140 return clock;
141}
142
11b0cdc8
JG
143int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
144 struct bt_ctf_clock *clock)
145{
146 int ret = 0;
eee752e5 147 struct bt_ctf_field_type *timestamp_field = NULL;
11b0cdc8
JG
148
149 if (!stream_class || !clock || stream_class->frozen) {
150 ret = -1;
151 goto end;
152 }
153
eee752e5
JG
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) {
83509119 167 bt_put(mapped_clock);
eee752e5
JG
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
11b0cdc8 178 if (stream_class->clock) {
83509119 179 bt_put(stream_class->clock);
11b0cdc8
JG
180 }
181
182 stream_class->clock = clock;
83509119 183 bt_get(clock);
11b0cdc8 184end:
eee752e5 185 if (timestamp_field) {
83509119 186 bt_put(timestamp_field);
eee752e5 187 }
11b0cdc8
JG
188 return ret;
189}
190
2f100782
JG
191int64_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;
201end:
202 return ret;
203}
204
5ca83563
JG
205BT_HIDDEN
206int _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
29664b2a
PP
214struct event_class_set_stream_id_data {
215 uint32_t stream_id;
216 int ret;
217};
218
219static
220void 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
228BT_HIDDEN
229int bt_ctf_stream_class_set_id_no_check(
230 struct bt_ctf_stream_class *stream_class, uint32_t id)
2f100782
JG
231{
232 int ret = 0;
29664b2a
PP
233 struct event_class_set_stream_id_data data =
234 { .stream_id = id, .ret = 0 };
2f100782 235
29664b2a
PP
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) {
2f100782
JG
244 goto end;
245 }
246
5ca83563
JG
247 ret = _bt_ctf_stream_class_set_id(stream_class, id);
248 if (ret) {
249 goto end;
250 }
2f100782
JG
251end:
252 return ret;
253}
254
29664b2a
PP
255int 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);
266end:
267 return ret;
268}
269
0d23acbe
PP
270static
271void 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
310end:
311 return;
312}
313
11b0cdc8
JG
314int 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;
2f100782 319 int64_t event_id;
e6a8e8e4
JG
320 struct bt_ctf_trace *trace = NULL;
321 struct bt_ctf_stream_class *old_stream_class = NULL;
09840de5
PP
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;
11b0cdc8
JG
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 };
0d23acbe
PP
339 g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
340 &query);
11b0cdc8
JG
341 if (query.found) {
342 ret = -1;
343 goto end;
344 }
345
09840de5 346 old_stream_class = bt_ctf_event_class_get_stream_class(event_class);
e6a8e8e4
JG
347 if (old_stream_class) {
348 /* Event class is already associated to a stream class. */
349 ret = -1;
350 goto end;
351 }
352
09840de5 353 trace = bt_ctf_stream_class_get_trace(stream_class);
e6a8e8e4 354 if (trace) {
09840de5
PP
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
26079216 394 if (ret) {
09840de5
PP
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;
26079216
JG
407 goto end;
408 }
409 }
410
09840de5 411 /* Only set an event ID if none was explicitly set before */
2f100782
JG
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
29664b2a
PP
421 ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
422 if (ret) {
423 goto end;
424 }
425
e6a8e8e4 426 bt_object_set_parent(event_class, stream_class);
09840de5
PP
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 */
11b0cdc8 447 g_ptr_array_add(stream_class->event_classes, event_class);
09840de5
PP
448
449 /* Freeze the event class */
58203827 450 bt_ctf_event_class_freeze(event_class);
5ca83563
JG
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
09840de5 458 * class is added to a trace.
5ca83563
JG
459 */
460 bt_ctf_event_class_set_native_byte_order(event_class,
461 stream_class->byte_order);
462 }
09840de5 463
11b0cdc8 464end:
e6a8e8e4
JG
465 BT_PUT(trace);
466 BT_PUT(old_stream_class);
09840de5
PP
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
11b0cdc8
JG
475 return ret;
476}
477
074ee56d 478int bt_ctf_stream_class_get_event_class_count(
69dc4535
JG
479 struct bt_ctf_stream_class *stream_class)
480{
074ee56d 481 int ret;
69dc4535
JG
482
483 if (!stream_class) {
484 ret = -1;
485 goto end;
486 }
487
074ee56d 488 ret = (int) stream_class->event_classes->len;
69dc4535
JG
489end:
490 return ret;
491}
492
493struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class(
074ee56d 494 struct bt_ctf_stream_class *stream_class, int index)
69dc4535
JG
495{
496 struct bt_ctf_event_class *event_class = NULL;
497
074ee56d
JG
498 if (!stream_class || index < 0 ||
499 index >= stream_class->event_classes->len) {
69dc4535
JG
500 goto end;
501 }
502
503 event_class = g_ptr_array_index(stream_class->event_classes, index);
83509119 504 bt_get(event_class);
69dc4535
JG
505end:
506 return event_class;
507}
508
509struct 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;
69dc4535
JG
513 struct bt_ctf_event_class *event_class = NULL;
514
515 if (!stream_class || !name) {
516 goto end;
517 }
518
69dc4535 519 for (i = 0; i < stream_class->event_classes->len; i++) {
b8248cc0 520 struct bt_ctf_event_class *cur_event_class =
69dc4535 521 g_ptr_array_index(stream_class->event_classes, i);
b8248cc0
PP
522 const char *cur_event_class_name =
523 bt_ctf_event_class_get_name(cur_event_class);
69dc4535 524
b8248cc0
PP
525 if (!strcmp(name, cur_event_class_name)) {
526 event_class = cur_event_class;
83509119 527 bt_get(event_class);
69dc4535
JG
528 goto end;
529 }
530 }
531end:
532 return event_class;
533}
534
0863f950
PP
535struct 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;
83509119 551 bt_get(event_class);
0863f950
PP
552 goto end;
553 }
554 }
555end:
556 return event_class;
557}
558
12c8a1a3
JG
559struct 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);
83509119 569 bt_get(stream_class->packet_context_type);
12c8a1a3
JG
570 ret = stream_class->packet_context_type;
571end:
572 return ret;
573}
574
575int 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
0a00bfa1 581 if (!stream_class || !packet_context_type || stream_class->frozen) {
12c8a1a3
JG
582 ret = -1;
583 goto end;
584 }
585
586 assert(stream_class->packet_context_type);
662e778c
JG
587 if (stream_class->packet_context_type == packet_context_type) {
588 goto end;
589 }
b34f4d90 590 if (bt_ctf_field_type_get_type_id(packet_context_type) !=
9a19a512 591 BT_CTF_TYPE_ID_STRUCT) {
12c8a1a3
JG
592 /* A packet context must be a structure */
593 ret = -1;
594 goto end;
595 }
596
83509119
JG
597 bt_put(stream_class->packet_context_type);
598 bt_get(packet_context_type);
12c8a1a3
JG
599 stream_class->packet_context_type = packet_context_type;
600end:
601 return ret;
602}
603
662e778c
JG
604struct 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);
83509119 614 bt_get(stream_class->event_header_type);
662e778c
JG
615 ret = stream_class->event_header_type;
616end:
617 return ret;
618}
619
620int 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) !=
9a19a512 636 BT_CTF_TYPE_ID_STRUCT) {
662e778c
JG
637 /* An event header must be a structure */
638 ret = -1;
639 goto end;
640 }
641
83509119
JG
642 bt_put(stream_class->event_header_type);
643 bt_get(event_header_type);
662e778c
JG
644 stream_class->event_header_type = event_header_type;
645end:
646 return ret;
647}
648
af181248
JG
649struct 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);
83509119 659 bt_get(stream_class->event_context_type);
af181248
JG
660 ret = stream_class->event_context_type;
661end:
662 return ret;
663}
664
665int 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) !=
9a19a512 677 BT_CTF_TYPE_ID_STRUCT) {
af181248
JG
678 /* A packet context must be a structure */
679 ret = -1;
680 goto end;
681 }
682
83509119
JG
683 bt_put(stream_class->event_context_type);
684 bt_get(event_context_type);
af181248
JG
685 stream_class->event_context_type = event_context_type;
686end:
687 return ret;
688}
689
11b0cdc8
JG
690void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
691{
83509119 692 bt_get(stream_class);
11b0cdc8
JG
693}
694
695void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
696{
83509119 697 bt_put(stream_class);
11b0cdc8
JG
698}
699
700BT_HIDDEN
701void 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;
662e778c 708 bt_ctf_field_type_freeze(stream_class->event_header_type);
12c8a1a3 709 bt_ctf_field_type_freeze(stream_class->packet_context_type);
af181248 710 bt_ctf_field_type_freeze(stream_class->event_context_type);
11b0cdc8 711 bt_ctf_clock_freeze(stream_class->clock);
11b0cdc8
JG
712}
713
11b0cdc8 714BT_HIDDEN
445c3471
PP
715void bt_ctf_stream_class_set_byte_order(
716 struct bt_ctf_stream_class *stream_class, int byte_order)
11b0cdc8 717{
445c3471 718 int i;
11b0cdc8 719
445c3471
PP
720 assert(stream_class);
721 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
722 stream_class->byte_order = byte_order;
5ca83563
JG
723
724 /* Set native byte order to little or big endian */
725 bt_ctf_field_type_set_native_byte_order(
445c3471 726 stream_class->event_header_type, byte_order);
5ca83563 727 bt_ctf_field_type_set_native_byte_order(
445c3471 728 stream_class->packet_context_type, byte_order);
5ca83563 729 bt_ctf_field_type_set_native_byte_order(
445c3471 730 stream_class->event_context_type, byte_order);
5ca83563
JG
731
732 /* Set all events' native byte order */
733 for (i = 0; i < stream_class->event_classes->len; i++) {
445c3471
PP
734 struct bt_ctf_event_class *event_class =
735 g_ptr_array_index(stream_class->event_classes, i);
9849f6ff 736
9849f6ff 737 bt_ctf_event_class_set_native_byte_order(event_class,
445c3471 738 byte_order);
5ca83563 739 }
11b0cdc8
JG
740}
741
742BT_HIDDEN
743int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
744 struct metadata_context *context)
745{
2f100782 746 int64_t ret = 0;
11b0cdc8
JG
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");
11b0cdc8
JG
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
11b0cdc8
JG
786 ret = bt_ctf_event_class_serialize(event_class, context);
787 if (ret) {
788 goto end;
789 }
790 }
791end:
792 context->current_indentation_level = 0;
793 return ret;
794}
795
796static
83509119 797void bt_ctf_stream_class_destroy(struct bt_object *obj)
11b0cdc8
JG
798{
799 struct bt_ctf_stream_class *stream_class;
800
83509119
JG
801 stream_class = container_of(obj, struct bt_ctf_stream_class, base);
802 bt_put(stream_class->clock);
11b0cdc8
JG
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
83509119
JG
812 bt_put(stream_class->event_header_type);
813 bt_put(stream_class->packet_context_type);
814 bt_put(stream_class->event_context_type);
11b0cdc8
JG
815 g_free(stream_class);
816}
817
818static
662e778c 819int init_event_header(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
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
11b0cdc8
JG
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
662e778c 846 if (stream_class->event_header_type) {
83509119 847 bt_put(stream_class->event_header_type);
de876b7f 848 }
662e778c 849 stream_class->event_header_type = event_header_type;
11b0cdc8
JG
850end:
851 if (ret) {
83509119 852 bt_put(event_header_type);
11b0cdc8
JG
853 }
854
83509119
JG
855 bt_put(_uint32_t);
856 bt_put(_uint64_t);
11b0cdc8
JG
857 return ret;
858}
859
860static
662e778c 861int init_packet_context(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
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 */
11b0cdc8
JG
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
83509119 908 bt_put(stream_class->packet_context_type);
11b0cdc8 909 stream_class->packet_context_type = packet_context_type;
11b0cdc8
JG
910end:
911 if (ret) {
83509119 912 bt_put(packet_context_type);
11b0cdc8
JG
913 goto end;
914 }
915
83509119 916 bt_put(_uint64_t);
11b0cdc8
JG
917 return ret;
918}
This page took 0.072984 seconds and 4 git commands to generate.