Split CTF IR and CTF writer APIs and implementations
[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
3dca2276 32#include <babeltrace/assert-pre-internal.h>
ac0c6bdd 33#include <babeltrace/ctf-ir/clock-class-internal.h>
272df73e 34#include <babeltrace/ctf-ir/event-class-internal.h>
2e33ac5a
PP
35#include <babeltrace/ctf-ir/field-types-internal.h>
36#include <babeltrace/ctf-ir/fields-internal.h>
11b0cdc8 37#include <babeltrace/ctf-ir/stream-class-internal.h>
09840de5 38#include <babeltrace/ctf-ir/validation-internal.h>
8bf65fbd 39#include <babeltrace/ctf-ir/visitor-internal.h>
654c1444 40#include <babeltrace/ctf-ir/utils.h>
2a3ced3c 41#include <babeltrace/ctf-ir/utils-internal.h>
83509119 42#include <babeltrace/ref.h>
3d9990ac
PP
43#include <babeltrace/compiler-internal.h>
44#include <babeltrace/align-internal.h>
45#include <babeltrace/endian-internal.h>
f6ccaed9 46#include <babeltrace/assert-internal.h>
dc3fffef 47#include <inttypes.h>
544d0515 48#include <stdint.h>
e011d2c1 49#include <stdbool.h>
11b0cdc8 50
3dca2276
PP
51BT_HIDDEN
52int bt_stream_class_common_initialize(struct bt_stream_class_common *stream_class,
53 const char *name, bt_object_release_func release_func)
e0e2946b 54{
3dca2276 55 BT_LOGD("Initializing common stream class object: name=\"%s\"", name);
11b0cdc8 56
3dca2276 57 bt_object_init(stream_class, release_func);
11b0cdc8
JG
58 stream_class->name = g_string_new(name);
59 stream_class->event_classes = g_ptr_array_new_with_free_func(
e6a8e8e4 60 (GDestroyNotify) bt_object_release);
11b0cdc8 61 if (!stream_class->event_classes) {
d2f71f12 62 BT_LOGE_STR("Failed to allocate a GPtrArray.");
83509119 63 goto error;
11b0cdc8
JG
64 }
65
0b9ce69f
JG
66 stream_class->event_classes_ht = g_hash_table_new_full(g_int64_hash,
67 g_int64_equal, g_free, NULL);
d2f71f12
PP
68 if (!stream_class->event_classes_ht) {
69 BT_LOGE_STR("Failed to allocate a GHashTable.");
70 goto error;
71 }
0b9ce69f 72
3dca2276 73 BT_LOGD("Initialized common stream class object: addr=%p, name=\"%s\"",
d2f71f12 74 stream_class, name);
3dca2276 75 return 0;
11b0cdc8 76
11b0cdc8 77error:
3dca2276 78 return -1;
142c5610
JG
79}
80
3dca2276
PP
81BT_HIDDEN
82void bt_stream_class_common_finalize(struct bt_stream_class_common *stream_class)
3ea33115 83{
3dca2276
PP
84 BT_LOGD("Finalizing common stream class: addr=%p, name=\"%s\", id=%" PRId64,
85 stream_class, bt_stream_class_common_get_name(stream_class),
86 bt_stream_class_common_get_id(stream_class));
87 bt_put(stream_class->clock_class);
3ea33115 88
3dca2276
PP
89 if (stream_class->event_classes_ht) {
90 g_hash_table_destroy(stream_class->event_classes_ht);
91 }
92 if (stream_class->event_classes) {
93 BT_LOGD_STR("Destroying event classes.");
94 g_ptr_array_free(stream_class->event_classes, TRUE);
d2f71f12
PP
95 }
96
3dca2276
PP
97 if (stream_class->name) {
98 g_string_free(stream_class->name, TRUE);
3ea33115
JG
99 }
100
3dca2276
PP
101 BT_LOGD_STR("Putting event header field type.");
102 bt_put(stream_class->event_header_field_type);
103 BT_LOGD_STR("Putting packet context field type.");
104 bt_put(stream_class->packet_context_field_type);
105 BT_LOGD_STR("Putting event context field type.");
106 bt_put(stream_class->event_context_field_type);
107}
03be3bcd 108
3dca2276
PP
109static
110void bt_stream_class_destroy(struct bt_object *obj)
111{
112 struct bt_stream_class *stream_class;
03be3bcd 113
3dca2276
PP
114 stream_class = (void *) obj;
115 BT_LOGD("Destroying stream class: addr=%p, name=\"%s\", id=%" PRId64,
50842bdc
PP
116 stream_class, bt_stream_class_get_name(stream_class),
117 bt_stream_class_get_id(stream_class));
3dca2276
PP
118 bt_stream_class_common_finalize(BT_TO_COMMON(stream_class));
119 g_free(stream_class);
3ea33115
JG
120}
121
3dca2276 122struct bt_stream_class *bt_stream_class_create(const char *name)
2f100782 123{
3dca2276
PP
124 struct bt_stream_class *stream_class = NULL;
125 int ret;
2f100782 126
3dca2276
PP
127 BT_LOGD("Creating stream class object: name=\"%s\"", name);
128 stream_class = g_new0(struct bt_stream_class, 1);
d2f71f12 129 if (!stream_class) {
3dca2276
PP
130 BT_LOGE_STR("Failed to allocate one stream class.");
131 goto error;
d2f71f12
PP
132 }
133
3dca2276
PP
134 ret = bt_stream_class_common_initialize(BT_TO_COMMON(stream_class),
135 name, bt_stream_class_destroy);
136 if (ret) {
137 /* bt_stream_class_common_initialize() logs errors */
138 goto error;
2f100782
JG
139 }
140
3dca2276
PP
141 BT_LOGD("Created stream class object: addr=%p, name=\"%s\"",
142 stream_class, name);
143 return stream_class;
144
145error:
146 bt_put(stream_class);
147 return NULL;
2f100782
JG
148}
149
3dca2276 150struct bt_trace *bt_stream_class_get_trace(struct bt_stream_class *stream_class)
11b0cdc8 151{
3dca2276
PP
152 return BT_FROM_COMMON(bt_stream_class_common_get_trace(
153 BT_TO_COMMON(stream_class)));
11b0cdc8
JG
154}
155
3dca2276 156const char *bt_stream_class_get_name(struct bt_stream_class *stream_class)
2f100782 157{
3dca2276 158 return bt_stream_class_common_get_name(BT_TO_COMMON(stream_class));
2f100782
JG
159}
160
3dca2276
PP
161int bt_stream_class_set_name(struct bt_stream_class *stream_class,
162 const char *name)
5ca83563 163{
3dca2276
PP
164 return bt_stream_class_common_set_name(BT_TO_COMMON(stream_class),
165 name);
5ca83563
JG
166}
167
3dca2276 168int64_t bt_stream_class_get_id(struct bt_stream_class *stream_class)
2f100782 169{
3dca2276 170 return bt_stream_class_common_get_id(BT_TO_COMMON(stream_class));
2f100782
JG
171}
172
3dca2276 173int bt_stream_class_set_id(struct bt_stream_class *stream_class, uint64_t id)
29664b2a 174{
3dca2276 175 return bt_stream_class_common_set_id(BT_TO_COMMON(stream_class), id);
29664b2a
PP
176}
177
0d23acbe
PP
178static
179void event_class_exists(gpointer element, gpointer query)
180{
3dca2276 181 struct bt_event_class_common *event_class_a = element;
0d23acbe 182 struct search_query *search_query = query;
3dca2276 183 struct bt_event_class_common *event_class_b = search_query->value;
0d23acbe
PP
184 int64_t id_a, id_b;
185
186 if (search_query->value == element) {
187 search_query->found = 1;
188 goto end;
189 }
190
0d23acbe
PP
191 /*
192 * Two event classes cannot share the same ID in a given
193 * stream class.
194 */
3dca2276
PP
195 id_a = bt_event_class_common_get_id(event_class_a);
196 id_b = bt_event_class_common_get_id(event_class_b);
0d23acbe
PP
197
198 if (id_a < 0 || id_b < 0) {
199 /* at least one ID is not set: will be automatically set later */
200 goto end;
201 }
202
203 if (id_a == id_b) {
66871d36 204 BT_LOGW("Event class with this ID already exists in the stream class: "
d2f71f12 205 "id=%" PRId64 ", name=\"%s\"",
3dca2276 206 id_a, bt_event_class_common_get_name(event_class_a));
0d23acbe
PP
207 search_query->found = 1;
208 goto end;
209 }
210
211end:
212 return;
213}
214
3dca2276
PP
215BT_HIDDEN
216int bt_stream_class_common_add_event_class(
217 struct bt_stream_class_common *stream_class,
218 struct bt_event_class_common *event_class,
219 bt_validation_flag_copy_field_type_func copy_field_type_func)
11b0cdc8
JG
220{
221 int ret = 0;
0b9ce69f 222 int64_t *event_id = NULL;
3dca2276
PP
223 struct bt_trace_common *trace = NULL;
224 struct bt_stream_class_common *old_stream_class = NULL;
50842bdc 225 struct bt_validation_output validation_output = { 0 };
3dca2276
PP
226 struct bt_field_type_common *packet_header_type = NULL;
227 struct bt_field_type_common *packet_context_type = NULL;
228 struct bt_field_type_common *event_header_type = NULL;
229 struct bt_field_type_common *stream_event_ctx_type = NULL;
230 struct bt_field_type_common *event_context_type = NULL;
231 struct bt_field_type_common *event_payload_type = NULL;
50842bdc
PP
232 const enum bt_validation_flag validation_flags =
233 BT_VALIDATION_FLAG_EVENT;
2a3ced3c 234 struct bt_clock_class *expected_clock_class = NULL;
11b0cdc8 235
3dca2276
PP
236 BT_ASSERT(copy_field_type_func);
237
e011d2c1
PP
238 if (!stream_class || !event_class) {
239 BT_LOGW("Invalid parameter: stream class or event class is NULL: "
240 "stream-class-addr=%p, event-class-addr=%p",
241 stream_class, event_class);
242 ret = -1;
243 goto end;
244 }
245
d2f71f12
PP
246 BT_LOGD("Adding event class to stream class: "
247 "stream-class-addr=%p, stream-class-name=\"%s\", "
248 "stream-class-id=%" PRId64 ", event-class-addr=%p, "
249 "event-class-name=\"%s\", event-class-id=%" PRId64,
3dca2276
PP
250 stream_class, bt_stream_class_common_get_name(stream_class),
251 bt_stream_class_common_get_id(stream_class),
d2f71f12 252 event_class,
3dca2276
PP
253 bt_event_class_common_get_name(event_class),
254 bt_event_class_common_get_id(event_class));
d2f71f12 255
3dca2276 256 trace = bt_stream_class_common_get_trace(stream_class);
5acf2ae6 257
2a3ced3c
PP
258 if (stream_class->frozen) {
259 /*
260 * We only check that the event class to be added has a
261 * single class which matches the stream class's
262 * expected clock class if the stream class is frozen.
263 * If it's not, then this event class is added "as is"
264 * and the validation will be performed when calling
265 * either bt_trace_add_stream_class() or
266 * bt_event_create(). This is because the stream class's
267 * field types (packet context, event header, event
268 * context) could change before the next call to one of
269 * those two functions.
270 */
271 expected_clock_class = bt_get(stream_class->clock_class);
272
273 /*
274 * At this point, `expected_clock_class` can be NULL,
275 * and bt_event_class_validate_single_clock_class()
276 * below can set it.
277 */
3dca2276 278 ret = bt_event_class_common_validate_single_clock_class(
2a3ced3c
PP
279 event_class, &expected_clock_class);
280 if (ret) {
281 BT_LOGW("Event class contains a field type which is not "
282 "recursively mapped to its stream class's "
283 "expected clock class: "
284 "stream-class-addr=%p, "
285 "stream-class-id=%" PRId64 ", "
286 "stream-class-name=\"%s\", "
287 "expected-clock-class-addr=%p, "
288 "expected-clock-class-name=\"%s\"",
289 stream_class,
3dca2276
PP
290 bt_stream_class_common_get_id(stream_class),
291 bt_stream_class_common_get_name(stream_class),
2a3ced3c
PP
292 expected_clock_class,
293 expected_clock_class ?
294 bt_clock_class_get_name(expected_clock_class) :
295 NULL);
296 goto end;
297 }
298 }
299
0b9ce69f
JG
300 event_id = g_new(int64_t, 1);
301 if (!event_id) {
d2f71f12 302 BT_LOGE_STR("Failed to allocate one int64_t.");
0b9ce69f
JG
303 ret = -1;
304 goto end;
305 }
306
11b0cdc8
JG
307 /* Check for duplicate event classes */
308 struct search_query query = { .value = event_class, .found = 0 };
0d23acbe
PP
309 g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
310 &query);
11b0cdc8 311 if (query.found) {
d2f71f12 312 BT_LOGW_STR("Another event class part of this stream class has the same ID.");
11b0cdc8
JG
313 ret = -1;
314 goto end;
315 }
316
3dca2276 317 old_stream_class = bt_event_class_common_borrow_stream_class(event_class);
e6a8e8e4
JG
318 if (old_stream_class) {
319 /* Event class is already associated to a stream class. */
d2f71f12
PP
320 BT_LOGW("Event class is already part of another stream class: "
321 "event-class-stream-class-addr=%p, "
322 "event-class-stream-class-name=\"%s\", "
323 "event-class-stream-class-id=%" PRId64,
324 old_stream_class,
3dca2276
PP
325 bt_stream_class_common_get_name(old_stream_class),
326 bt_stream_class_common_get_id(old_stream_class));
e6a8e8e4
JG
327 ret = -1;
328 goto end;
329 }
330
e6a8e8e4 331 if (trace) {
09840de5
PP
332 /*
333 * If the stream class is associated with a trace, then
334 * both those objects are frozen. Also, this event class
335 * is about to be frozen.
336 *
337 * Therefore the event class must be validated here.
338 * The trace and stream class should be valid at this
339 * point.
340 */
f6ccaed9
PP
341 BT_ASSERT(trace->valid);
342 BT_ASSERT(stream_class->valid);
09840de5 343 packet_header_type =
3dca2276 344 bt_trace_common_get_packet_header_field_type(trace);
09840de5 345 packet_context_type =
3dca2276 346 bt_stream_class_common_get_packet_context_field_type(
09840de5
PP
347 stream_class);
348 event_header_type =
3dca2276
PP
349 bt_stream_class_common_get_event_header_field_type(
350 stream_class);
09840de5 351 stream_event_ctx_type =
3dca2276 352 bt_stream_class_common_get_event_context_field_type(
09840de5
PP
353 stream_class);
354 event_context_type =
3dca2276 355 bt_event_class_common_get_context_field_type(event_class);
09840de5 356 event_payload_type =
3dca2276 357 bt_event_class_common_get_payload_field_type(event_class);
50842bdc 358 ret = bt_validate_class_types(
09840de5
PP
359 trace->environment, packet_header_type,
360 packet_context_type, event_header_type,
361 stream_event_ctx_type, event_context_type,
362 event_payload_type, trace->valid,
363 stream_class->valid, event_class->valid,
3dca2276
PP
364 &validation_output, validation_flags,
365 copy_field_type_func);
09840de5
PP
366 BT_PUT(packet_header_type);
367 BT_PUT(packet_context_type);
368 BT_PUT(event_header_type);
369 BT_PUT(stream_event_ctx_type);
370 BT_PUT(event_context_type);
371 BT_PUT(event_payload_type);
372
26079216 373 if (ret) {
09840de5
PP
374 /*
375 * This means something went wrong during the
376 * validation process, not that the objects are
377 * invalid.
378 */
d2f71f12 379 BT_LOGE("Failed to validate event class: ret=%d", ret);
09840de5
PP
380 goto end;
381 }
382
383 if ((validation_output.valid_flags & validation_flags) !=
384 validation_flags) {
385 /* Invalid event class */
66871d36 386 BT_LOGW("Invalid trace, stream class, or event class: "
d2f71f12
PP
387 "valid-flags=0x%x",
388 validation_output.valid_flags);
09840de5 389 ret = -1;
26079216
JG
390 goto end;
391 }
392 }
393
09840de5 394 /* Only set an event ID if none was explicitly set before */
3dca2276 395 *event_id = bt_event_class_common_get_id(event_class);
24626e8b 396 if (*event_id < 0) {
d2f71f12
PP
397 BT_LOGV("Event class has no ID: automatically setting it: "
398 "id=%" PRId64, stream_class->next_event_id);
399
3dca2276 400 if (bt_event_class_common_set_id(event_class,
d2f71f12
PP
401 stream_class->next_event_id)) {
402 BT_LOGE("Cannot set event class's ID: id=%" PRId64,
403 stream_class->next_event_id);
2f100782
JG
404 ret = -1;
405 goto end;
406 }
d2f71f12 407 stream_class->next_event_id++;
0b9ce69f 408 *event_id = stream_class->next_event_id;
2f100782
JG
409 }
410
e6a8e8e4 411 bt_object_set_parent(event_class, stream_class);
09840de5
PP
412
413 if (trace) {
414 /*
415 * At this point we know that the function will be
416 * successful. Therefore we can replace the event
417 * class's field types with what's in the validation
418 * output structure and mark this event class as valid.
419 */
50842bdc 420 bt_validation_replace_types(NULL, NULL, event_class,
09840de5
PP
421 &validation_output, validation_flags);
422 event_class->valid = 1;
423
424 /*
425 * Put what was not moved in
50842bdc 426 * bt_validation_replace_types().
09840de5 427 */
50842bdc 428 bt_validation_output_put_types(&validation_output);
09840de5
PP
429 }
430
431 /* Add to the event classes of the stream class */
11b0cdc8 432 g_ptr_array_add(stream_class->event_classes, event_class);
0b9ce69f
JG
433 g_hash_table_insert(stream_class->event_classes_ht, event_id,
434 event_class);
435 event_id = NULL;
09840de5
PP
436
437 /* Freeze the event class */
3dca2276 438 bt_event_class_common_freeze(event_class);
5ca83563 439
2a3ced3c
PP
440 /*
441 * It is safe to set the stream class's unique clock class
442 * now if the stream class is frozen.
443 */
444 if (stream_class->frozen && expected_clock_class) {
f6ccaed9 445 BT_ASSERT(!stream_class->clock_class ||
2a3ced3c
PP
446 stream_class->clock_class == expected_clock_class);
447 BT_MOVE(stream_class->clock_class, expected_clock_class);
448 }
449
d2f71f12
PP
450 BT_LOGD("Added event class to stream class: "
451 "stream-class-addr=%p, stream-class-name=\"%s\", "
452 "stream-class-id=%" PRId64 ", event-class-addr=%p, "
453 "event-class-name=\"%s\", event-class-id=%" PRId64,
3dca2276
PP
454 stream_class, bt_stream_class_common_get_name(stream_class),
455 bt_stream_class_common_get_id(stream_class),
d2f71f12 456 event_class,
3dca2276
PP
457 bt_event_class_common_get_name(event_class),
458 bt_event_class_common_get_id(event_class));
d2f71f12 459
11b0cdc8 460end:
e6a8e8e4 461 BT_PUT(trace);
50842bdc 462 bt_validation_output_put_types(&validation_output);
2a3ced3c 463 bt_put(expected_clock_class);
f6ccaed9
PP
464 BT_ASSERT(!packet_header_type);
465 BT_ASSERT(!packet_context_type);
466 BT_ASSERT(!event_header_type);
467 BT_ASSERT(!stream_event_ctx_type);
468 BT_ASSERT(!event_context_type);
469 BT_ASSERT(!event_payload_type);
0b9ce69f 470 g_free(event_id);
11b0cdc8
JG
471 return ret;
472}
473
3dca2276
PP
474int bt_stream_class_add_event_class(
475 struct bt_stream_class *stream_class,
476 struct bt_event_class *event_class)
69dc4535 477{
3dca2276
PP
478 struct bt_trace *trace;
479 int ret = 0;
69dc4535
JG
480
481 if (!stream_class) {
3dca2276
PP
482 BT_LOGW("Invalid parameter: stream class is NULL: "
483 "stream-class-addr=%p", stream_class);
484 ret = -1;
485 goto end;
486 }
487
488 trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
489 BT_TO_COMMON(stream_class)));
490 if (trace && trace->is_static) {
491 BT_LOGW("Invalid parameter: stream class's trace is static: "
492 "trace-addr=%p, trace-name=\"%s\"",
493 trace, bt_trace_get_name(trace));
494 ret = -1;
495 goto end;
496 }
497
498 ret = bt_stream_class_common_add_event_class(
499 BT_TO_COMMON(stream_class), BT_TO_COMMON(event_class),
500 (bt_validation_flag_copy_field_type_func) bt_field_type_copy);
501 if (ret) {
69dc4535
JG
502 goto end;
503 }
504
3dca2276
PP
505 /* Notifiy listeners of the trace's schema modification. */
506 if (trace) {
507 struct bt_visitor_object obj = { .object = event_class,
508 .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS };
509
510 (void) bt_trace_object_modification(&obj, trace);
511 }
512
69dc4535
JG
513end:
514 return ret;
515}
516
3dca2276
PP
517int64_t bt_stream_class_get_event_class_count(
518 struct bt_stream_class *stream_class)
519{
520 return bt_stream_class_common_get_event_class_count(
521 BT_TO_COMMON(stream_class));
522}
523
50842bdc
PP
524struct bt_event_class *bt_stream_class_get_event_class_by_index(
525 struct bt_stream_class *stream_class, uint64_t index)
69dc4535 526{
3dca2276
PP
527 return BT_FROM_COMMON(bt_stream_class_common_get_event_class_by_index(
528 BT_TO_COMMON(stream_class), index));
69dc4535
JG
529}
530
50842bdc
PP
531struct bt_event_class *bt_stream_class_get_event_class_by_id(
532 struct bt_stream_class *stream_class, uint64_t id)
0863f950 533{
3dca2276
PP
534 return BT_FROM_COMMON(bt_stream_class_common_get_event_class_by_id(
535 BT_TO_COMMON(stream_class), id));
0863f950
PP
536}
537
3dca2276 538struct bt_field_type *bt_stream_class_get_packet_context_field_type(
50842bdc 539 struct bt_stream_class *stream_class)
12c8a1a3 540{
3dca2276
PP
541 return BT_FROM_COMMON(bt_stream_class_common_get_packet_context_field_type(
542 BT_TO_COMMON(stream_class)));
12c8a1a3
JG
543}
544
3dca2276 545int bt_stream_class_set_packet_context_field_type(
50842bdc
PP
546 struct bt_stream_class *stream_class,
547 struct bt_field_type *packet_context_type)
12c8a1a3 548{
3dca2276
PP
549 return bt_stream_class_common_set_packet_context_field_type(
550 BT_TO_COMMON(stream_class), (void *) packet_context_type);
12c8a1a3
JG
551}
552
3dca2276 553struct bt_field_type *bt_stream_class_get_event_header_field_type(
50842bdc 554 struct bt_stream_class *stream_class)
662e778c 555{
3dca2276
PP
556 return BT_FROM_COMMON(bt_stream_class_common_get_event_header_field_type(
557 BT_TO_COMMON(stream_class)));
662e778c
JG
558}
559
3dca2276 560int bt_stream_class_set_event_header_field_type(
50842bdc
PP
561 struct bt_stream_class *stream_class,
562 struct bt_field_type *event_header_type)
662e778c 563{
3dca2276
PP
564 return bt_stream_class_common_set_event_header_field_type(
565 BT_TO_COMMON(stream_class), (void *) event_header_type);
662e778c
JG
566}
567
3dca2276 568struct bt_field_type *bt_stream_class_get_event_context_field_type(
50842bdc 569 struct bt_stream_class *stream_class)
af181248 570{
3dca2276
PP
571 return BT_FROM_COMMON(bt_stream_class_common_get_event_context_field_type(
572 BT_TO_COMMON(stream_class)));
af181248
JG
573}
574
3dca2276 575int bt_stream_class_set_event_context_field_type(
50842bdc
PP
576 struct bt_stream_class *stream_class,
577 struct bt_field_type *event_context_type)
af181248 578{
3dca2276
PP
579 return bt_stream_class_common_set_event_context_field_type(
580 BT_TO_COMMON(stream_class), (void *) event_context_type);
11b0cdc8
JG
581}
582
8bf65fbd 583static
544d0515 584int64_t get_event_class_count(void *element)
8bf65fbd 585{
50842bdc
PP
586 return bt_stream_class_get_event_class_count(
587 (struct bt_stream_class *) element);
8bf65fbd
JG
588}
589
590static
591void *get_event_class(void *element, int i)
592{
50842bdc
PP
593 return bt_stream_class_get_event_class_by_index(
594 (struct bt_stream_class *) element, i);
8bf65fbd
JG
595}
596
597static
50842bdc 598int visit_event_class(void *object, bt_visitor visitor,void *data)
8bf65fbd 599{
3dca2276
PP
600 struct bt_visitor_object obj = {
601 .object = object,
602 .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS
603 };
8bf65fbd 604
d9a13d86 605 return visitor(&obj, data);
8bf65fbd
JG
606}
607
3dca2276
PP
608BT_HIDDEN
609int bt_stream_class_common_visit(struct bt_stream_class_common *stream_class,
50842bdc 610 bt_visitor visitor, void *data)
8bf65fbd
JG
611{
612 int ret;
3dca2276
PP
613 struct bt_visitor_object obj = {
614 .object = stream_class,
615 .type = BT_VISITOR_OBJECT_TYPE_STREAM_CLASS
616 };
8bf65fbd
JG
617
618 if (!stream_class || !visitor) {
d2f71f12
PP
619 BT_LOGW("Invalid parameter: stream class or visitor is NULL: "
620 "stream-class-addr=%p, visitor=%p",
621 stream_class, visitor);
8bf65fbd
JG
622 ret = -1;
623 goto end;
624 }
625
d9a13d86 626 ret = visitor_helper(&obj, get_event_class_count,
8bf65fbd
JG
627 get_event_class,
628 visit_event_class, visitor, data);
d2f71f12 629 BT_LOGV("visitor_helper() returned: ret=%d", ret);
3dca2276 630
8bf65fbd
JG
631end:
632 return ret;
633}
634
3dca2276
PP
635int bt_stream_class_visit(struct bt_stream_class *stream_class,
636 bt_visitor visitor, void *data)
637{
638 return bt_stream_class_common_visit(BT_FROM_COMMON(stream_class),
639 visitor, data);
640}
641
11b0cdc8 642BT_HIDDEN
3dca2276 643void bt_stream_class_common_freeze(struct bt_stream_class_common *stream_class)
11b0cdc8 644{
d2f71f12 645 if (!stream_class || stream_class->frozen) {
11b0cdc8
JG
646 return;
647 }
648
d2f71f12 649 BT_LOGD("Freezing stream class: addr=%p, name=\"%s\", id=%" PRId64,
3dca2276
PP
650 stream_class, bt_stream_class_common_get_name(stream_class),
651 bt_stream_class_common_get_id(stream_class));
11b0cdc8 652 stream_class->frozen = 1;
3dca2276
PP
653 bt_field_type_common_freeze(stream_class->event_header_field_type);
654 bt_field_type_common_freeze(stream_class->packet_context_field_type);
655 bt_field_type_common_freeze(stream_class->event_context_field_type);
656 bt_clock_class_freeze(stream_class->clock_class);
11b0cdc8
JG
657}
658
3dca2276 659void bt_stream_class_freeze(struct bt_stream_class *stream_class)
e011d2c1 660{
3dca2276 661 bt_stream_class_common_freeze(BT_TO_COMMON(stream_class));
11b0cdc8 662}
2a3ced3c
PP
663
664BT_HIDDEN
3dca2276
PP
665int bt_stream_class_common_validate_single_clock_class(
666 struct bt_stream_class_common *stream_class,
2a3ced3c
PP
667 struct bt_clock_class **expected_clock_class)
668{
669 int ret;
670 uint64_t i;
671
f6ccaed9
PP
672 BT_ASSERT(stream_class);
673 BT_ASSERT(expected_clock_class);
3dca2276
PP
674 ret = bt_field_type_common_validate_single_clock_class(
675 stream_class->packet_context_field_type,
2a3ced3c
PP
676 expected_clock_class);
677 if (ret) {
678 BT_LOGW("Stream class's packet context field type "
679 "is not recursively mapped to the "
680 "expected clock class: "
681 "stream-class-addr=%p, "
682 "stream-class-name=\"%s\", "
683 "stream-class-id=%" PRId64 ", "
684 "ft-addr=%p",
685 stream_class,
3dca2276 686 bt_stream_class_common_get_name(stream_class),
2a3ced3c 687 stream_class->id,
3dca2276 688 stream_class->packet_context_field_type);
2a3ced3c
PP
689 goto end;
690 }
691
3dca2276
PP
692 ret = bt_field_type_common_validate_single_clock_class(
693 stream_class->event_header_field_type,
2a3ced3c
PP
694 expected_clock_class);
695 if (ret) {
696 BT_LOGW("Stream class's event header field type "
697 "is not recursively mapped to the "
698 "expected clock class: "
699 "stream-class-addr=%p, "
700 "stream-class-name=\"%s\", "
701 "stream-class-id=%" PRId64 ", "
702 "ft-addr=%p",
703 stream_class,
3dca2276 704 bt_stream_class_common_get_name(stream_class),
2a3ced3c 705 stream_class->id,
3dca2276 706 stream_class->event_header_field_type);
2a3ced3c
PP
707 goto end;
708 }
709
3dca2276
PP
710 ret = bt_field_type_common_validate_single_clock_class(
711 stream_class->event_context_field_type,
2a3ced3c
PP
712 expected_clock_class);
713 if (ret) {
714 BT_LOGW("Stream class's event context field type "
715 "is not recursively mapped to the "
716 "expected clock class: "
717 "stream-class-addr=%p, "
718 "stream-class-name=\"%s\", "
719 "stream-class-id=%" PRId64 ", "
720 "ft-addr=%p",
721 stream_class,
3dca2276 722 bt_stream_class_common_get_name(stream_class),
2a3ced3c 723 stream_class->id,
3dca2276 724 stream_class->event_context_field_type);
2a3ced3c
PP
725 goto end;
726 }
727
728 for (i = 0; i < stream_class->event_classes->len; i++) {
3dca2276 729 struct bt_event_class_common *event_class =
2a3ced3c
PP
730 g_ptr_array_index(stream_class->event_classes, i);
731
f6ccaed9 732 BT_ASSERT(event_class);
3dca2276
PP
733 ret = bt_event_class_common_validate_single_clock_class(
734 event_class, expected_clock_class);
2a3ced3c
PP
735 if (ret) {
736 BT_LOGW("Stream class's event class contains a "
737 "field type which is not recursively mapped to "
738 "the expected clock class: "
739 "stream-class-addr=%p, "
740 "stream-class-name=\"%s\", "
741 "stream-class-id=%" PRId64,
742 stream_class,
3dca2276 743 bt_stream_class_common_get_name(stream_class),
2a3ced3c
PP
744 stream_class->id);
745 goto end;
746 }
747 }
748
749end:
750 return ret;
751}
This page took 0.082626 seconds and 4 git commands to generate.