Event notification: make sure contained event has a trace
[babeltrace.git] / lib / 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
d2f71f12
PP
29#define BT_LOG_TAG "STREAM-CLASS"
30#include <babeltrace/lib-logging-internal.h>
31
11b0cdc8 32#include <babeltrace/ctf-writer/clock.h>
ac0c6bdd
PP
33#include <babeltrace/ctf-writer/clock-internal.h>
34#include <babeltrace/ctf-ir/clock-class-internal.h>
11b0cdc8 35#include <babeltrace/ctf-writer/event.h>
272df73e 36#include <babeltrace/ctf-ir/event-class-internal.h>
11b0cdc8 37#include <babeltrace/ctf-ir/event-internal.h>
2e33ac5a
PP
38#include <babeltrace/ctf-ir/field-types-internal.h>
39#include <babeltrace/ctf-ir/fields-internal.h>
11b0cdc8
JG
40#include <babeltrace/ctf-writer/stream.h>
41#include <babeltrace/ctf-ir/stream-class-internal.h>
09840de5 42#include <babeltrace/ctf-ir/validation-internal.h>
8bf65fbd 43#include <babeltrace/ctf-ir/visitor-internal.h>
11b0cdc8 44#include <babeltrace/ctf-writer/functor-internal.h>
654c1444 45#include <babeltrace/ctf-ir/utils.h>
83509119 46#include <babeltrace/ref.h>
3d9990ac
PP
47#include <babeltrace/compiler-internal.h>
48#include <babeltrace/align-internal.h>
49#include <babeltrace/endian-internal.h>
dc3fffef 50#include <inttypes.h>
544d0515 51#include <stdint.h>
11b0cdc8
JG
52
53static
83509119 54void bt_ctf_stream_class_destroy(struct bt_object *obj);
11b0cdc8 55static
662e778c 56int init_event_header(struct bt_ctf_stream_class *stream_class);
11b0cdc8 57static
662e778c 58int init_packet_context(struct bt_ctf_stream_class *stream_class);
11b0cdc8
JG
59
60struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
61{
d2f71f12 62 struct bt_ctf_stream_class *stream_class;
12c8a1a3 63 int ret;
e0e2946b 64
d2f71f12
PP
65 BT_LOGD("Creating default stream class object: name=\"%s\"", name);
66 stream_class = bt_ctf_stream_class_create_empty(name);
e0e2946b 67 if (!stream_class) {
d2f71f12 68 BT_LOGD_STR("Cannot create empty stream class.");
e0e2946b
PP
69 goto error;
70 }
71
72 ret = init_event_header(stream_class);
73 if (ret) {
d2f71f12 74 BT_LOGE_STR("Cannot initialize stream class's event header field type.");
e0e2946b
PP
75 goto error;
76 }
77
78 ret = init_packet_context(stream_class);
79 if (ret) {
d2f71f12 80 BT_LOGE_STR("Cannot initialize stream class's packet context field type.");
e0e2946b
PP
81 goto error;
82 }
83
d2f71f12
PP
84 BT_LOGD("Created default stream class object: addr=%p, name=\"%s\"",
85 stream_class, name);
e0e2946b
PP
86 return stream_class;
87
88error:
89 BT_PUT(stream_class);
90 return stream_class;
91}
92
93struct bt_ctf_stream_class *bt_ctf_stream_class_create_empty(const char *name)
94{
11b0cdc8
JG
95 struct bt_ctf_stream_class *stream_class = NULL;
96
d2f71f12
PP
97 BT_LOGD("Creating empty stream class object: name=\"%s\"", name);
98
3ea33115 99 if (name && bt_ctf_validate_identifier(name)) {
d2f71f12
PP
100 BT_LOGW("Invalid parameter: stream class's name is not a valid CTF identifier: "
101 "name=\"%s\"", name);
11b0cdc8
JG
102 goto error;
103 }
104
105 stream_class = g_new0(struct bt_ctf_stream_class, 1);
106 if (!stream_class) {
d2f71f12 107 BT_LOGE_STR("Failed to allocate one stream class.");
11b0cdc8
JG
108 goto error;
109 }
110
111 stream_class->name = g_string_new(name);
112 stream_class->event_classes = g_ptr_array_new_with_free_func(
e6a8e8e4 113 (GDestroyNotify) bt_object_release);
11b0cdc8 114 if (!stream_class->event_classes) {
d2f71f12 115 BT_LOGE_STR("Failed to allocate a GPtrArray.");
83509119 116 goto error;
11b0cdc8
JG
117 }
118
0b9ce69f
JG
119 stream_class->event_classes_ht = g_hash_table_new_full(g_int64_hash,
120 g_int64_equal, g_free, NULL);
d2f71f12
PP
121 if (!stream_class->event_classes_ht) {
122 BT_LOGE_STR("Failed to allocate a GHashTable.");
123 goto error;
124 }
0b9ce69f 125
e0e2946b
PP
126 stream_class->packet_context_type = bt_ctf_field_type_structure_create();
127 if (!stream_class->packet_context_type) {
40f7101a 128 BT_LOGE_STR("Cannot create stream class's initial packet context field type.");
83509119 129 goto error;
662e778c
JG
130 }
131
e0e2946b
PP
132 stream_class->event_header_type = bt_ctf_field_type_structure_create();
133 if (!stream_class->event_header_type) {
40f7101a 134 BT_LOGE_STR("Cannot create stream class's initial event header field type.");
e0e2946b
PP
135 goto error;
136 }
137
138 stream_class->event_context_type = bt_ctf_field_type_structure_create();
139 if (!stream_class->event_context_type) {
40f7101a 140 BT_LOGE_STR("Cannot create stream class's initial event context field type.");
83509119 141 goto error;
12c8a1a3
JG
142 }
143
83509119 144 bt_object_init(stream_class, bt_ctf_stream_class_destroy);
d2f71f12
PP
145 BT_LOGD("Created empty stream class object: addr=%p, name=\"%s\"",
146 stream_class, name);
11b0cdc8
JG
147 return stream_class;
148
11b0cdc8 149error:
e0e2946b 150 BT_PUT(stream_class);
11b0cdc8
JG
151 return stream_class;
152}
153
142c5610
JG
154struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
155 struct bt_ctf_stream_class *stream_class)
156{
dc3fffef
PP
157 return stream_class ?
158 bt_get(bt_ctf_stream_class_borrow_trace(stream_class)) :
159 NULL;
142c5610
JG
160}
161
69dc4535
JG
162const char *bt_ctf_stream_class_get_name(
163 struct bt_ctf_stream_class *stream_class)
164{
165 const char *name = NULL;
166
167 if (!stream_class) {
d2f71f12 168 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
69dc4535
JG
169 goto end;
170 }
171
172 name = stream_class->name->str;
173end:
174 return name;
175}
176
3ea33115
JG
177int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
178 const char *name)
179{
180 int ret = 0;
181
d2f71f12
PP
182 if (!stream_class) {
183 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
184 ret = -1;
185 goto end;
186 }
187
188 if (stream_class->frozen) {
189 BT_LOGW("Invalid parameter: stream class is frozen: "
190 "addr=%p, name=\"%s\", id=%" PRId64,
191 stream_class, bt_ctf_stream_class_get_name(stream_class),
192 bt_ctf_stream_class_get_id(stream_class));
3ea33115
JG
193 ret = -1;
194 goto end;
195 }
196
197 g_string_assign(stream_class->name, name);
d2f71f12
PP
198 BT_LOGV("Set stream class's name: "
199 "addr=%p, name=\"%s\", id=%" PRId64,
200 stream_class, bt_ctf_stream_class_get_name(stream_class),
201 bt_ctf_stream_class_get_id(stream_class));
3ea33115
JG
202end:
203 return ret;
204}
205
2f100782
JG
206struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
207 struct bt_ctf_stream_class *stream_class)
208{
209 struct bt_ctf_clock *clock = NULL;
210
d2f71f12
PP
211 if (!stream_class) {
212 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
213 goto end;
214 }
215
216 if (!stream_class->clock) {
217 BT_LOGV("Stream class has no clock: "
218 "addr=%p, name=\"%s\", id=%" PRId64,
219 stream_class, bt_ctf_stream_class_get_name(stream_class),
220 bt_ctf_stream_class_get_id(stream_class));
2f100782
JG
221 goto end;
222 }
223
ac0c6bdd 224 clock = bt_get(stream_class->clock);
2f100782
JG
225end:
226 return clock;
227}
228
11b0cdc8
JG
229int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
230 struct bt_ctf_clock *clock)
231{
232 int ret = 0;
eee752e5 233 struct bt_ctf_field_type *timestamp_field = NULL;
11b0cdc8 234
d2f71f12
PP
235 if (!stream_class || !clock) {
236 BT_LOGW("Invalid parameter: stream class or clock is NULL: "
237 "stream-class-addr=%p, clock-addr=%p",
238 stream_class, clock);
239 ret = -1;
240 goto end;
241 }
242
243 if (stream_class->frozen) {
244 BT_LOGW("Invalid parameter: stream class is frozen: "
245 "addr=%p, name=\"%s\", id=%" PRId64,
246 stream_class, bt_ctf_stream_class_get_name(stream_class),
247 bt_ctf_stream_class_get_id(stream_class));
11b0cdc8
JG
248 ret = -1;
249 goto end;
250 }
251
eee752e5 252 /*
ac0c6bdd
PP
253 * Look for a "timestamp" integer field type in the stream
254 * class's event header field type and map the stream class's
255 * clock's class to that field type if there's no current
256 * mapping.
eee752e5
JG
257 */
258 timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
259 stream_class->event_header_type, "timestamp");
260 if (timestamp_field) {
ac0c6bdd
PP
261 struct bt_ctf_clock_class *mapped_clock_class =
262 bt_ctf_field_type_integer_get_mapped_clock_class(
263 timestamp_field);
264
265 if (!mapped_clock_class) {
266 ret = bt_ctf_field_type_integer_set_mapped_clock_class(
267 timestamp_field, clock->clock_class);
268 if (ret) {
269 goto end;
270 }
eee752e5
JG
271 }
272
ac0c6bdd 273 BT_PUT(mapped_clock_class);
eee752e5
JG
274 }
275
ac0c6bdd
PP
276 /* Replace the current clock of this stream class. */
277 bt_put(stream_class->clock);
278 stream_class->clock = bt_get(clock);
d2f71f12
PP
279 BT_LOGV("Set stream class's clock: "
280 "addr=%p, name=\"%s\", id=%" PRId64 ", "
281 "clock-addr=%p, clock-name=\"%s\"",
282 stream_class, bt_ctf_stream_class_get_name(stream_class),
283 bt_ctf_stream_class_get_id(stream_class),
284 stream_class->clock,
285 bt_ctf_clock_get_name(stream_class->clock));
11b0cdc8 286
11b0cdc8 287end:
ac0c6bdd 288 bt_put(timestamp_field);
11b0cdc8
JG
289 return ret;
290}
291
2f100782
JG
292int64_t bt_ctf_stream_class_get_id(struct bt_ctf_stream_class *stream_class)
293{
294 int64_t ret;
295
d2f71f12
PP
296 if (!stream_class) {
297 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
298 ret = (int64_t) -1;
299 goto end;
300 }
301
302 if (!stream_class->id_set) {
303 BT_LOGV("Stream class's ID is not set: addr=%p, name=\"%s\"",
304 stream_class,
305 bt_ctf_stream_class_get_name(stream_class));
9ac68eb1 306 ret = (int64_t) -1;
2f100782
JG
307 goto end;
308 }
309
9ac68eb1 310 ret = stream_class->id;
2f100782
JG
311end:
312 return ret;
313}
314
5ca83563 315BT_HIDDEN
d2f71f12 316void _bt_ctf_stream_class_set_id(
9ac68eb1 317 struct bt_ctf_stream_class *stream_class, int64_t id)
5ca83563 318{
d2f71f12 319 assert(stream_class);
5ca83563
JG
320 stream_class->id = id;
321 stream_class->id_set = 1;
d2f71f12
PP
322 BT_LOGV("Set stream class's ID (internal): "
323 "addr=%p, name=\"%s\", id=%" PRId64,
324 stream_class, bt_ctf_stream_class_get_name(stream_class),
325 bt_ctf_stream_class_get_id(stream_class));
5ca83563
JG
326}
327
9ac68eb1
PP
328struct event_class_set_stream_class_id_data {
329 int64_t stream_class_id;
29664b2a
PP
330 int ret;
331};
332
333static
334void event_class_set_stream_id(gpointer event_class, gpointer data)
335{
9ac68eb1 336 struct event_class_set_stream_class_id_data *typed_data = data;
29664b2a
PP
337
338 typed_data->ret |= bt_ctf_event_class_set_stream_id(event_class,
9ac68eb1 339 typed_data->stream_class_id);
29664b2a
PP
340}
341
342BT_HIDDEN
343int bt_ctf_stream_class_set_id_no_check(
9ac68eb1 344 struct bt_ctf_stream_class *stream_class, int64_t id)
2f100782
JG
345{
346 int ret = 0;
9ac68eb1
PP
347 struct event_class_set_stream_class_id_data data =
348 { .stream_class_id = id, .ret = 0 };
2f100782 349
29664b2a
PP
350 /*
351 * Make sure all event classes have their "stream_id" attribute
352 * set to this value.
353 */
354 g_ptr_array_foreach(stream_class->event_classes,
355 event_class_set_stream_id, &data);
356 ret = data.ret;
357 if (ret) {
d2f71f12
PP
358 BT_LOGE("Cannot set the IDs of all stream class's event classes: "
359 "addr=%p, name=\"%s\", id=%" PRId64,
360 stream_class, bt_ctf_stream_class_get_name(stream_class),
361 bt_ctf_stream_class_get_id(stream_class));
2f100782
JG
362 goto end;
363 }
364
d2f71f12 365 _bt_ctf_stream_class_set_id(stream_class, id);
2f100782
JG
366end:
367 return ret;
368}
369
29664b2a 370int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
9ac68eb1 371 uint64_t id_param)
29664b2a
PP
372{
373 int ret = 0;
9ac68eb1 374 int64_t id = (int64_t) id_param;
29664b2a 375
d2f71f12
PP
376 if (!stream_class) {
377 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
378 ret = -1;
379 goto end;
380 }
381
382 if (stream_class->frozen) {
383 BT_LOGW("Invalid parameter: stream class is frozen: "
384 "addr=%p, name=\"%s\", id=%" PRId64,
385 stream_class, bt_ctf_stream_class_get_name(stream_class),
386 bt_ctf_stream_class_get_id(stream_class));
387 ret = -1;
388 goto end;
389 }
390
391 if (id < 0) {
392 BT_LOGW("Invalid parameter: invalid stream class's ID: "
393 "stream-class-addr=%p, stream-class-name=\"%s\", "
394 "stream-class-id=%" PRId64 ", id=%" PRIu64,
395 stream_class, bt_ctf_stream_class_get_name(stream_class),
396 bt_ctf_stream_class_get_id(stream_class),
397 id_param);
29664b2a
PP
398 ret = -1;
399 goto end;
400 }
401
402 ret = bt_ctf_stream_class_set_id_no_check(stream_class, id);
d2f71f12
PP
403 if (ret == 0) {
404 BT_LOGV("Set stream class's ID: "
405 "addr=%p, name=\"%s\", id=%" PRId64,
406 stream_class, bt_ctf_stream_class_get_name(stream_class),
407 bt_ctf_stream_class_get_id(stream_class));
408 }
29664b2a
PP
409end:
410 return ret;
411}
412
0d23acbe
PP
413static
414void event_class_exists(gpointer element, gpointer query)
415{
416 struct bt_ctf_event_class *event_class_a = element;
417 struct search_query *search_query = query;
418 struct bt_ctf_event_class *event_class_b = search_query->value;
419 int64_t id_a, id_b;
420
421 if (search_query->value == element) {
422 search_query->found = 1;
423 goto end;
424 }
425
0d23acbe
PP
426 /*
427 * Two event classes cannot share the same ID in a given
428 * stream class.
429 */
430 id_a = bt_ctf_event_class_get_id(event_class_a);
431 id_b = bt_ctf_event_class_get_id(event_class_b);
432
433 if (id_a < 0 || id_b < 0) {
434 /* at least one ID is not set: will be automatically set later */
435 goto end;
436 }
437
438 if (id_a == id_b) {
66871d36 439 BT_LOGW("Event class with this ID already exists in the stream class: "
d2f71f12
PP
440 "id=%" PRId64 ", name=\"%s\"",
441 id_a, bt_ctf_event_class_get_name(event_class_a));
0d23acbe
PP
442 search_query->found = 1;
443 goto end;
444 }
445
446end:
447 return;
448}
449
11b0cdc8
JG
450int bt_ctf_stream_class_add_event_class(
451 struct bt_ctf_stream_class *stream_class,
452 struct bt_ctf_event_class *event_class)
453{
454 int ret = 0;
0b9ce69f 455 int64_t *event_id = NULL;
e6a8e8e4
JG
456 struct bt_ctf_trace *trace = NULL;
457 struct bt_ctf_stream_class *old_stream_class = NULL;
09840de5
PP
458 struct bt_ctf_validation_output validation_output = { 0 };
459 struct bt_ctf_field_type *packet_header_type = NULL;
460 struct bt_ctf_field_type *packet_context_type = NULL;
461 struct bt_ctf_field_type *event_header_type = NULL;
462 struct bt_ctf_field_type *stream_event_ctx_type = NULL;
463 struct bt_ctf_field_type *event_context_type = NULL;
464 struct bt_ctf_field_type *event_payload_type = NULL;
465 const enum bt_ctf_validation_flag validation_flags =
466 BT_CTF_VALIDATION_FLAG_EVENT;
11b0cdc8 467
d2f71f12
PP
468 BT_LOGD("Adding event class to stream class: "
469 "stream-class-addr=%p, stream-class-name=\"%s\", "
470 "stream-class-id=%" PRId64 ", event-class-addr=%p, "
471 "event-class-name=\"%s\", event-class-id=%" PRId64,
472 stream_class, bt_ctf_stream_class_get_name(stream_class),
473 bt_ctf_stream_class_get_id(stream_class),
474 event_class,
475 bt_ctf_event_class_get_name(event_class),
476 bt_ctf_event_class_get_id(event_class));
477
11b0cdc8 478 if (!stream_class || !event_class) {
d2f71f12
PP
479 BT_LOGW("Invalid parameter: stream class or event class is NULL: "
480 "stream-class-addr=%p, event-class-addr=%p",
481 stream_class, event_class);
11b0cdc8
JG
482 ret = -1;
483 goto end;
484 }
485
5acf2ae6
PP
486 trace = bt_ctf_stream_class_get_trace(stream_class);
487 if (trace && trace->is_static) {
488 ret = -1;
489 goto end;
490 }
491
0b9ce69f
JG
492 event_id = g_new(int64_t, 1);
493 if (!event_id) {
d2f71f12 494 BT_LOGE_STR("Failed to allocate one int64_t.");
0b9ce69f
JG
495 ret = -1;
496 goto end;
497 }
498
11b0cdc8
JG
499 /* Check for duplicate event classes */
500 struct search_query query = { .value = event_class, .found = 0 };
0d23acbe
PP
501 g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
502 &query);
11b0cdc8 503 if (query.found) {
d2f71f12 504 BT_LOGW_STR("Another event class part of this stream class has the same ID.");
11b0cdc8
JG
505 ret = -1;
506 goto end;
507 }
508
09840de5 509 old_stream_class = bt_ctf_event_class_get_stream_class(event_class);
e6a8e8e4
JG
510 if (old_stream_class) {
511 /* Event class is already associated to a stream class. */
d2f71f12
PP
512 BT_LOGW("Event class is already part of another stream class: "
513 "event-class-stream-class-addr=%p, "
514 "event-class-stream-class-name=\"%s\", "
515 "event-class-stream-class-id=%" PRId64,
516 old_stream_class,
517 bt_ctf_stream_class_get_name(old_stream_class),
518 bt_ctf_stream_class_get_id(old_stream_class));
e6a8e8e4
JG
519 ret = -1;
520 goto end;
521 }
522
e6a8e8e4 523 if (trace) {
09840de5
PP
524 /*
525 * If the stream class is associated with a trace, then
526 * both those objects are frozen. Also, this event class
527 * is about to be frozen.
528 *
529 * Therefore the event class must be validated here.
530 * The trace and stream class should be valid at this
531 * point.
532 */
533 assert(trace->valid);
534 assert(stream_class->valid);
535 packet_header_type =
536 bt_ctf_trace_get_packet_header_type(trace);
537 packet_context_type =
538 bt_ctf_stream_class_get_packet_context_type(
539 stream_class);
540 event_header_type =
541 bt_ctf_stream_class_get_event_header_type(stream_class);
542 stream_event_ctx_type =
543 bt_ctf_stream_class_get_event_context_type(
544 stream_class);
545 event_context_type =
546 bt_ctf_event_class_get_context_type(event_class);
547 event_payload_type =
548 bt_ctf_event_class_get_payload_type(event_class);
549 ret = bt_ctf_validate_class_types(
550 trace->environment, packet_header_type,
551 packet_context_type, event_header_type,
552 stream_event_ctx_type, event_context_type,
553 event_payload_type, trace->valid,
554 stream_class->valid, event_class->valid,
555 &validation_output, validation_flags);
556 BT_PUT(packet_header_type);
557 BT_PUT(packet_context_type);
558 BT_PUT(event_header_type);
559 BT_PUT(stream_event_ctx_type);
560 BT_PUT(event_context_type);
561 BT_PUT(event_payload_type);
562
26079216 563 if (ret) {
09840de5
PP
564 /*
565 * This means something went wrong during the
566 * validation process, not that the objects are
567 * invalid.
568 */
d2f71f12 569 BT_LOGE("Failed to validate event class: ret=%d", ret);
09840de5
PP
570 goto end;
571 }
572
573 if ((validation_output.valid_flags & validation_flags) !=
574 validation_flags) {
575 /* Invalid event class */
66871d36 576 BT_LOGW("Invalid trace, stream class, or event class: "
d2f71f12
PP
577 "valid-flags=0x%x",
578 validation_output.valid_flags);
09840de5 579 ret = -1;
26079216
JG
580 goto end;
581 }
582 }
583
09840de5 584 /* Only set an event ID if none was explicitly set before */
0b9ce69f 585 *event_id = bt_ctf_event_class_get_id(event_class);
24626e8b 586 if (*event_id < 0) {
d2f71f12
PP
587 BT_LOGV("Event class has no ID: automatically setting it: "
588 "id=%" PRId64, stream_class->next_event_id);
589
2f100782 590 if (bt_ctf_event_class_set_id(event_class,
d2f71f12
PP
591 stream_class->next_event_id)) {
592 BT_LOGE("Cannot set event class's ID: id=%" PRId64,
593 stream_class->next_event_id);
2f100782
JG
594 ret = -1;
595 goto end;
596 }
d2f71f12 597 stream_class->next_event_id++;
0b9ce69f 598 *event_id = stream_class->next_event_id;
2f100782
JG
599 }
600
29664b2a
PP
601 ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
602 if (ret) {
d2f71f12
PP
603 BT_LOGE("Cannot set event class's stream class ID attribute: ret=%d",
604 ret);
29664b2a
PP
605 goto end;
606 }
607
e6a8e8e4 608 bt_object_set_parent(event_class, stream_class);
09840de5
PP
609
610 if (trace) {
611 /*
612 * At this point we know that the function will be
613 * successful. Therefore we can replace the event
614 * class's field types with what's in the validation
615 * output structure and mark this event class as valid.
616 */
617 bt_ctf_validation_replace_types(NULL, NULL, event_class,
618 &validation_output, validation_flags);
619 event_class->valid = 1;
620
621 /*
622 * Put what was not moved in
623 * bt_ctf_validation_replace_types().
624 */
625 bt_ctf_validation_output_put_types(&validation_output);
626 }
627
628 /* Add to the event classes of the stream class */
11b0cdc8 629 g_ptr_array_add(stream_class->event_classes, event_class);
0b9ce69f
JG
630 g_hash_table_insert(stream_class->event_classes_ht, event_id,
631 event_class);
632 event_id = NULL;
09840de5
PP
633
634 /* Freeze the event class */
58203827 635 bt_ctf_event_class_freeze(event_class);
5ca83563 636
9b888ff3
JG
637 /* Notifiy listeners of the trace's schema modification. */
638 if (trace) {
d9a13d86
PP
639 struct bt_ctf_object obj = { .object = event_class,
640 .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
9b888ff3 641
d9a13d86 642 (void) bt_ctf_trace_object_modification(&obj, trace);
9b888ff3 643 }
d2f71f12
PP
644
645 BT_LOGD("Added event class to stream class: "
646 "stream-class-addr=%p, stream-class-name=\"%s\", "
647 "stream-class-id=%" PRId64 ", event-class-addr=%p, "
648 "event-class-name=\"%s\", event-class-id=%" PRId64,
649 stream_class, bt_ctf_stream_class_get_name(stream_class),
650 bt_ctf_stream_class_get_id(stream_class),
651 event_class,
652 bt_ctf_event_class_get_name(event_class),
653 bt_ctf_event_class_get_id(event_class));
654
11b0cdc8 655end:
e6a8e8e4
JG
656 BT_PUT(trace);
657 BT_PUT(old_stream_class);
09840de5
PP
658 bt_ctf_validation_output_put_types(&validation_output);
659 assert(!packet_header_type);
660 assert(!packet_context_type);
661 assert(!event_header_type);
662 assert(!stream_event_ctx_type);
663 assert(!event_context_type);
664 assert(!event_payload_type);
0b9ce69f 665 g_free(event_id);
09840de5 666
11b0cdc8
JG
667 return ret;
668}
669
544d0515 670int64_t bt_ctf_stream_class_get_event_class_count(
69dc4535
JG
671 struct bt_ctf_stream_class *stream_class)
672{
544d0515 673 int64_t ret;
69dc4535
JG
674
675 if (!stream_class) {
d2f71f12 676 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
9ac68eb1 677 ret = (int64_t) -1;
69dc4535
JG
678 goto end;
679 }
680
9ac68eb1 681 ret = (int64_t) stream_class->event_classes->len;
69dc4535
JG
682end:
683 return ret;
684}
685
9ac68eb1
PP
686struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_index(
687 struct bt_ctf_stream_class *stream_class, uint64_t index)
69dc4535
JG
688{
689 struct bt_ctf_event_class *event_class = NULL;
690
d2f71f12
PP
691 if (!stream_class) {
692 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
693 goto end;
694 }
695
696 if (index >= stream_class->event_classes->len) {
697 BT_LOGW("Invalid parameter: index is out of bounds: "
698 "addr=%p, name=\"%s\", id=%" PRId64 ", "
699 "index=%" PRIu64 ", count=%u",
700 stream_class, bt_ctf_stream_class_get_name(stream_class),
701 bt_ctf_stream_class_get_id(stream_class),
702 index, stream_class->event_classes->len);
69dc4535
JG
703 goto end;
704 }
705
706 event_class = g_ptr_array_index(stream_class->event_classes, index);
83509119 707 bt_get(event_class);
69dc4535
JG
708end:
709 return event_class;
710}
711
0863f950 712struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
9ac68eb1 713 struct bt_ctf_stream_class *stream_class, uint64_t id)
0863f950 714{
9ac68eb1 715 int64_t id_key = (int64_t) id;
0863f950
PP
716 struct bt_ctf_event_class *event_class = NULL;
717
d2f71f12
PP
718 if (!stream_class) {
719 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
720 goto end;
721 }
722
723 if (id_key < 0) {
724 BT_LOGW("Invalid parameter: invalid event class's ID: "
725 "stream-class-addr=%p, stream-class-name=\"%s\", "
726 "stream-class-id=%" PRId64 ", event-class-id=%" PRIu64,
727 stream_class,
728 bt_ctf_stream_class_get_name(stream_class),
729 bt_ctf_stream_class_get_id(stream_class), id);
0863f950
PP
730 goto end;
731 }
732
0b9ce69f
JG
733 event_class = g_hash_table_lookup(stream_class->event_classes_ht,
734 &id_key);
735 bt_get(event_class);
0863f950
PP
736end:
737 return event_class;
738}
739
12c8a1a3
JG
740struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
741 struct bt_ctf_stream_class *stream_class)
742{
743 struct bt_ctf_field_type *ret = NULL;
744
745 if (!stream_class) {
d2f71f12 746 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
12c8a1a3
JG
747 goto end;
748 }
749
83509119 750 bt_get(stream_class->packet_context_type);
12c8a1a3
JG
751 ret = stream_class->packet_context_type;
752end:
753 return ret;
754}
755
756int bt_ctf_stream_class_set_packet_context_type(
757 struct bt_ctf_stream_class *stream_class,
758 struct bt_ctf_field_type *packet_context_type)
759{
760 int ret = 0;
761
d2f71f12
PP
762 if (!stream_class) {
763 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
764 ret = -1;
765 goto end;
766 }
767
768 if (stream_class->frozen) {
769 BT_LOGW("Invalid parameter: stream class is frozen: "
770 "addr=%p, name=\"%s\", id=%" PRId64,
771 stream_class, bt_ctf_stream_class_get_name(stream_class),
772 bt_ctf_stream_class_get_id(stream_class));
12c8a1a3
JG
773 ret = -1;
774 goto end;
775 }
776
835b2d10
JG
777 if (packet_context_type &&
778 bt_ctf_field_type_get_type_id(packet_context_type) !=
1487a16a 779 BT_CTF_FIELD_TYPE_ID_STRUCT) {
835b2d10 780 /* A packet context must be a structure. */
d2f71f12
PP
781 BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
782 "addr=%p, name=\"%s\", id=%" PRId64 ", "
783 "packet-context-ft-addr=%p, packet-context-ft-id=%s",
784 stream_class, bt_ctf_stream_class_get_name(stream_class),
785 bt_ctf_stream_class_get_id(stream_class),
786 packet_context_type,
787 bt_ctf_field_type_id_string(
788 bt_ctf_field_type_get_type_id(packet_context_type)));
12c8a1a3
JG
789 ret = -1;
790 goto end;
791 }
792
83509119
JG
793 bt_put(stream_class->packet_context_type);
794 bt_get(packet_context_type);
12c8a1a3 795 stream_class->packet_context_type = packet_context_type;
d2f71f12
PP
796 BT_LOGV("Set stream class's packet context field type: "
797 "addr=%p, name=\"%s\", id=%" PRId64 ", "
798 "packet-context-ft-addr=%p",
799 stream_class, bt_ctf_stream_class_get_name(stream_class),
800 bt_ctf_stream_class_get_id(stream_class),
801 packet_context_type);
802
12c8a1a3
JG
803end:
804 return ret;
805}
806
662e778c
JG
807struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
808 struct bt_ctf_stream_class *stream_class)
809{
810 struct bt_ctf_field_type *ret = NULL;
811
d2f71f12
PP
812 if (!stream_class) {
813 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
814 goto end;
815 }
816
817 if (!stream_class->event_header_type) {
818 BT_LOGV("Stream class has no event header field type: "
819 "addr=%p, name=\"%s\", id=%" PRId64,
820 stream_class, bt_ctf_stream_class_get_name(stream_class),
821 bt_ctf_stream_class_get_id(stream_class));
662e778c
JG
822 goto end;
823 }
824
83509119 825 bt_get(stream_class->event_header_type);
662e778c
JG
826 ret = stream_class->event_header_type;
827end:
828 return ret;
829}
830
831int bt_ctf_stream_class_set_event_header_type(
832 struct bt_ctf_stream_class *stream_class,
833 struct bt_ctf_field_type *event_header_type)
834{
835 int ret = 0;
836
d2f71f12
PP
837 if (!stream_class) {
838 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
839 ret = -1;
840 goto end;
841 }
842
843 if (stream_class->frozen) {
844 BT_LOGW("Invalid parameter: stream class is frozen: "
845 "addr=%p, name=\"%s\", id=%" PRId64,
846 stream_class, bt_ctf_stream_class_get_name(stream_class),
847 bt_ctf_stream_class_get_id(stream_class));
662e778c
JG
848 ret = -1;
849 goto end;
850 }
851
835b2d10
JG
852 if (event_header_type &&
853 bt_ctf_field_type_get_type_id(event_header_type) !=
1487a16a 854 BT_CTF_FIELD_TYPE_ID_STRUCT) {
835b2d10 855 /* An event header must be a structure. */
d2f71f12
PP
856 BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
857 "addr=%p, name=\"%s\", id=%" PRId64 ", "
858 "event-header-ft-addr=%p, event-header-ft-id=%s",
859 stream_class, bt_ctf_stream_class_get_name(stream_class),
860 bt_ctf_stream_class_get_id(stream_class),
861 event_header_type,
862 bt_ctf_field_type_id_string(
863 bt_ctf_field_type_get_type_id(event_header_type)));
662e778c
JG
864 ret = -1;
865 goto end;
866 }
867
83509119 868 bt_put(stream_class->event_header_type);
835b2d10 869 stream_class->event_header_type = bt_get(event_header_type);
d2f71f12
PP
870 BT_LOGV("Set stream class's event header field type: "
871 "addr=%p, name=\"%s\", id=%" PRId64 ", "
872 "event-header-ft-addr=%p",
873 stream_class, bt_ctf_stream_class_get_name(stream_class),
874 bt_ctf_stream_class_get_id(stream_class),
875 event_header_type);
662e778c
JG
876end:
877 return ret;
878}
879
af181248
JG
880struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
881 struct bt_ctf_stream_class *stream_class)
882{
883 struct bt_ctf_field_type *ret = NULL;
884
d2f71f12
PP
885 if (!stream_class) {
886 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
887 goto end;
888 }
889
890 if (!stream_class->event_context_type) {
af181248
JG
891 goto end;
892 }
893
83509119 894 bt_get(stream_class->event_context_type);
af181248
JG
895 ret = stream_class->event_context_type;
896end:
897 return ret;
898}
899
900int bt_ctf_stream_class_set_event_context_type(
901 struct bt_ctf_stream_class *stream_class,
902 struct bt_ctf_field_type *event_context_type)
903{
904 int ret = 0;
905
d2f71f12
PP
906 if (!stream_class) {
907 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
908 ret = -1;
909 goto end;
910 }
911
912 if (stream_class->frozen) {
913 BT_LOGW("Invalid parameter: stream class is frozen: "
914 "addr=%p, name=\"%s\", id=%" PRId64,
915 stream_class, bt_ctf_stream_class_get_name(stream_class),
916 bt_ctf_stream_class_get_id(stream_class));
af181248
JG
917 ret = -1;
918 goto end;
919 }
920
835b2d10
JG
921 if (event_context_type &&
922 bt_ctf_field_type_get_type_id(event_context_type) !=
1487a16a 923 BT_CTF_FIELD_TYPE_ID_STRUCT) {
835b2d10 924 /* A packet context must be a structure. */
d2f71f12
PP
925 BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
926 "addr=%p, name=\"%s\", id=%" PRId64 ", "
927 "event-context-ft-addr=%p, event-context-ft-id=%s",
928 stream_class, bt_ctf_stream_class_get_name(stream_class),
929 bt_ctf_stream_class_get_id(stream_class),
930 event_context_type,
931 bt_ctf_field_type_id_string(
932 bt_ctf_field_type_get_type_id(event_context_type)));
af181248
JG
933 ret = -1;
934 goto end;
935 }
936
83509119 937 bt_put(stream_class->event_context_type);
835b2d10 938 stream_class->event_context_type = bt_get(event_context_type);
d2f71f12
PP
939 BT_LOGV("Set stream class's event context field type: "
940 "addr=%p, name=\"%s\", id=%" PRId64 ", "
941 "event-context-ft-addr=%p",
942 stream_class, bt_ctf_stream_class_get_name(stream_class),
943 bt_ctf_stream_class_get_id(stream_class),
944 event_context_type);
af181248
JG
945end:
946 return ret;
947}
948
d2f71f12 949/* Pre-2.0 CTF writer backward compatibility */
11b0cdc8
JG
950void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
951{
83509119 952 bt_get(stream_class);
11b0cdc8
JG
953}
954
d2f71f12 955/* Pre-2.0 CTF writer backward compatibility */
11b0cdc8
JG
956void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
957{
83509119 958 bt_put(stream_class);
11b0cdc8
JG
959}
960
8bf65fbd 961static
544d0515 962int64_t get_event_class_count(void *element)
8bf65fbd
JG
963{
964 return bt_ctf_stream_class_get_event_class_count(
965 (struct bt_ctf_stream_class *) element);
966}
967
968static
969void *get_event_class(void *element, int i)
970{
9ac68eb1 971 return bt_ctf_stream_class_get_event_class_by_index(
8bf65fbd
JG
972 (struct bt_ctf_stream_class *) element, i);
973}
974
975static
d9a13d86 976int visit_event_class(void *object, bt_ctf_visitor visitor,void *data)
8bf65fbd 977{
d9a13d86
PP
978 struct bt_ctf_object obj =
979 { .object = object,
980 .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
8bf65fbd 981
d9a13d86 982 return visitor(&obj, data);
8bf65fbd
JG
983}
984
985int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
d9a13d86 986 bt_ctf_visitor visitor, void *data)
8bf65fbd
JG
987{
988 int ret;
d9a13d86
PP
989 struct bt_ctf_object obj =
990 { .object = stream_class,
991 .type = BT_CTF_OBJECT_TYPE_STREAM_CLASS };
8bf65fbd
JG
992
993 if (!stream_class || !visitor) {
d2f71f12
PP
994 BT_LOGW("Invalid parameter: stream class or visitor is NULL: "
995 "stream-class-addr=%p, visitor=%p",
996 stream_class, visitor);
8bf65fbd
JG
997 ret = -1;
998 goto end;
999 }
1000
d9a13d86 1001 ret = visitor_helper(&obj, get_event_class_count,
8bf65fbd
JG
1002 get_event_class,
1003 visit_event_class, visitor, data);
d2f71f12 1004 BT_LOGV("visitor_helper() returned: ret=%d", ret);
8bf65fbd
JG
1005end:
1006 return ret;
1007}
1008
11b0cdc8
JG
1009BT_HIDDEN
1010void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class)
1011{
d2f71f12 1012 if (!stream_class || stream_class->frozen) {
11b0cdc8
JG
1013 return;
1014 }
1015
d2f71f12
PP
1016 BT_LOGD("Freezing stream class: addr=%p, name=\"%s\", id=%" PRId64,
1017 stream_class, bt_ctf_stream_class_get_name(stream_class),
1018 bt_ctf_stream_class_get_id(stream_class));
11b0cdc8 1019 stream_class->frozen = 1;
662e778c 1020 bt_ctf_field_type_freeze(stream_class->event_header_type);
12c8a1a3 1021 bt_ctf_field_type_freeze(stream_class->packet_context_type);
af181248 1022 bt_ctf_field_type_freeze(stream_class->event_context_type);
ac0c6bdd
PP
1023
1024 if (stream_class->clock) {
1025 bt_ctf_clock_class_freeze(stream_class->clock->clock_class);
1026 }
11b0cdc8
JG
1027}
1028
11b0cdc8
JG
1029BT_HIDDEN
1030int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
1031 struct metadata_context *context)
1032{
9ac68eb1 1033 int ret = 0;
11b0cdc8
JG
1034 size_t i;
1035
d2f71f12
PP
1036 BT_LOGD("Serializing stream class's metadata: "
1037 "stream-class-addr=%p, stream-class-name=\"%s\", "
1038 "stream-class-id=%" PRId64 ", metadata-context-addr=%p",
1039 stream_class, bt_ctf_stream_class_get_name(stream_class),
1040 bt_ctf_stream_class_get_id(stream_class), context);
11b0cdc8
JG
1041 g_string_assign(context->field_name, "");
1042 context->current_indentation_level = 1;
1043 if (!stream_class->id_set) {
d2f71f12 1044 BT_LOGW_STR("Stream class's ID is not set.");
11b0cdc8
JG
1045 ret = -1;
1046 goto end;
1047 }
1048
1049 g_string_append_printf(context->string,
9ac68eb1 1050 "stream {\n\tid = %" PRId64 ";\n\tevent.header := ",
11b0cdc8
JG
1051 stream_class->id);
1052 ret = bt_ctf_field_type_serialize(stream_class->event_header_type,
1053 context);
1054 if (ret) {
66871d36 1055 BT_LOGW("Cannot serialize stream class's event header field type's metadata: "
d2f71f12 1056 "ret=%d", ret);
11b0cdc8
JG
1057 goto end;
1058 }
1059
98edd02c
JG
1060 if (stream_class->packet_context_type) {
1061 g_string_append(context->string, ";\n\n\tpacket.context := ");
1062 ret = bt_ctf_field_type_serialize(stream_class->packet_context_type,
1063 context);
1064 if (ret) {
66871d36 1065 BT_LOGW("Cannot serialize stream class's packet context field type's metadata: "
d2f71f12 1066 "ret=%d", ret);
98edd02c
JG
1067 goto end;
1068 }
11b0cdc8
JG
1069 }
1070
1071 if (stream_class->event_context_type) {
1072 g_string_append(context->string, ";\n\n\tevent.context := ");
1073 ret = bt_ctf_field_type_serialize(
1074 stream_class->event_context_type, context);
1075 if (ret) {
66871d36 1076 BT_LOGW("Cannot serialize stream class's event context field type's metadata: "
d2f71f12 1077 "ret=%d", ret);
11b0cdc8
JG
1078 goto end;
1079 }
1080 }
1081
1082 g_string_append(context->string, ";\n};\n\n");
11b0cdc8
JG
1083 for (i = 0; i < stream_class->event_classes->len; i++) {
1084 struct bt_ctf_event_class *event_class =
1085 stream_class->event_classes->pdata[i];
1086
11b0cdc8
JG
1087 ret = bt_ctf_event_class_serialize(event_class, context);
1088 if (ret) {
66871d36 1089 BT_LOGW("Cannot serialize event class's metadata: "
d2f71f12
PP
1090 "event-class-addr=%p, event-class-name=\"%s\", "
1091 "event-class-id=%" PRId64,
1092 event_class,
1093 bt_ctf_event_class_get_name(event_class),
1094 bt_ctf_event_class_get_id(event_class));
11b0cdc8
JG
1095 goto end;
1096 }
1097 }
1098end:
1099 context->current_indentation_level = 0;
1100 return ret;
1101}
1102
1103static
83509119 1104void bt_ctf_stream_class_destroy(struct bt_object *obj)
11b0cdc8
JG
1105{
1106 struct bt_ctf_stream_class *stream_class;
1107
83509119 1108 stream_class = container_of(obj, struct bt_ctf_stream_class, base);
d2f71f12
PP
1109 BT_LOGD("Destroying stream class: addr=%p, name=\"%s\", id=%" PRId64,
1110 stream_class, bt_ctf_stream_class_get_name(stream_class),
1111 bt_ctf_stream_class_get_id(stream_class));
83509119 1112 bt_put(stream_class->clock);
11b0cdc8 1113
0b9ce69f
JG
1114 if (stream_class->event_classes_ht) {
1115 g_hash_table_destroy(stream_class->event_classes_ht);
1116 }
11b0cdc8
JG
1117 if (stream_class->event_classes) {
1118 g_ptr_array_free(stream_class->event_classes, TRUE);
1119 }
1120
1121 if (stream_class->name) {
1122 g_string_free(stream_class->name, TRUE);
1123 }
1124
83509119
JG
1125 bt_put(stream_class->event_header_type);
1126 bt_put(stream_class->packet_context_type);
1127 bt_put(stream_class->event_context_type);
11b0cdc8
JG
1128 g_free(stream_class);
1129}
1130
1131static
662e778c 1132int init_event_header(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
1133{
1134 int ret = 0;
1135 struct bt_ctf_field_type *event_header_type =
1136 bt_ctf_field_type_structure_create();
1137 struct bt_ctf_field_type *_uint32_t =
1138 get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
1139 struct bt_ctf_field_type *_uint64_t =
1140 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
1141
1142 if (!event_header_type) {
d2f71f12 1143 BT_LOGE_STR("Cannot create empty structure field type.");
11b0cdc8
JG
1144 ret = -1;
1145 goto end;
1146 }
1147
11b0cdc8
JG
1148 ret = bt_ctf_field_type_structure_add_field(event_header_type,
1149 _uint32_t, "id");
1150 if (ret) {
d2f71f12 1151 BT_LOGE_STR("Cannot add `id` field to event header field type.");
11b0cdc8
JG
1152 goto end;
1153 }
1154
1155 ret = bt_ctf_field_type_structure_add_field(event_header_type,
1156 _uint64_t, "timestamp");
1157 if (ret) {
d2f71f12 1158 BT_LOGE_STR("Cannot add `timestamp` field to event header field type.");
11b0cdc8
JG
1159 goto end;
1160 }
1161
e0e2946b 1162 BT_MOVE(stream_class->event_header_type, event_header_type);
11b0cdc8
JG
1163end:
1164 if (ret) {
83509119 1165 bt_put(event_header_type);
11b0cdc8
JG
1166 }
1167
83509119
JG
1168 bt_put(_uint32_t);
1169 bt_put(_uint64_t);
11b0cdc8
JG
1170 return ret;
1171}
1172
1173static
662e778c 1174int init_packet_context(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
1175{
1176 int ret = 0;
1177 struct bt_ctf_field_type *packet_context_type =
1178 bt_ctf_field_type_structure_create();
1179 struct bt_ctf_field_type *_uint64_t =
1180 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
1181
1182 if (!packet_context_type) {
d2f71f12 1183 BT_LOGE_STR("Cannot create empty structure field type.");
11b0cdc8
JG
1184 ret = -1;
1185 goto end;
1186 }
1187
1188 /*
1189 * We create a stream packet context as proposed in the CTF
1190 * specification.
1191 */
11b0cdc8
JG
1192 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
1193 _uint64_t, "timestamp_begin");
1194 if (ret) {
d2f71f12 1195 BT_LOGE_STR("Cannot add `timestamp_begin` field to event header field type.");
11b0cdc8
JG
1196 goto end;
1197 }
1198
1199 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
1200 _uint64_t, "timestamp_end");
1201 if (ret) {
d2f71f12 1202 BT_LOGE_STR("Cannot add `timestamp_end` field to event header field type.");
11b0cdc8
JG
1203 goto end;
1204 }
1205
1206 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
1207 _uint64_t, "content_size");
1208 if (ret) {
d2f71f12 1209 BT_LOGE_STR("Cannot add `content_size` field to event header field type.");
11b0cdc8
JG
1210 goto end;
1211 }
1212
1213 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
1214 _uint64_t, "packet_size");
1215 if (ret) {
d2f71f12 1216 BT_LOGE_STR("Cannot add `packet_size` field to event header field type.");
11b0cdc8
JG
1217 goto end;
1218 }
1219
1220 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
1221 _uint64_t, "events_discarded");
1222 if (ret) {
d2f71f12 1223 BT_LOGE_STR("Cannot add `events_discarded` field to event header field type.");
11b0cdc8
JG
1224 goto end;
1225 }
1226
e0e2946b 1227 BT_MOVE(stream_class->packet_context_type, packet_context_type);
11b0cdc8
JG
1228end:
1229 if (ret) {
83509119 1230 bt_put(packet_context_type);
11b0cdc8
JG
1231 goto end;
1232 }
1233
83509119 1234 bt_put(_uint64_t);
11b0cdc8
JG
1235 return ret;
1236}
This page took 0.093948 seconds and 4 git commands to generate.