Cleanup: Use a switch case instead of conditionals
[babeltrace.git] / formats / ctf / ir / event.c
CommitLineData
273b65be
JG
1/*
2 * event.c
3 *
d2dc44b6 4 * Babeltrace CTF IR - Event
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
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/event.h>
30#include <babeltrace/ctf-writer/event-types.h>
31#include <babeltrace/ctf-writer/event-fields.h>
adc315b8
JG
32#include <babeltrace/ctf-ir/event-fields-internal.h>
33#include <babeltrace/ctf-ir/event-types-internal.h>
34#include <babeltrace/ctf-ir/event-internal.h>
2f100782 35#include <babeltrace/ctf-ir/stream-class.h>
c35a1669 36#include <babeltrace/ctf-ir/stream-class-internal.h>
bc37ae52 37#include <babeltrace/ctf-ir/trace-internal.h>
654c1444 38#include <babeltrace/ctf-ir/utils.h>
273b65be
JG
39#include <babeltrace/compiler.h>
40
41static
42void bt_ctf_event_class_destroy(struct bt_ctf_ref *ref);
43static
44void bt_ctf_event_destroy(struct bt_ctf_ref *ref);
45
46struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
47{
48 struct bt_ctf_event_class *event_class = NULL;
49
654c1444 50 if (bt_ctf_validate_identifier(name)) {
273b65be
JG
51 goto end;
52 }
53
54 event_class = g_new0(struct bt_ctf_event_class, 1);
55 if (!event_class) {
56 goto end;
57 }
58
59 bt_ctf_ref_init(&event_class->ref_count);
60 event_class->name = g_quark_from_string(name);
61end:
62 return event_class;
63}
64
2f100782
JG
65const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
66{
67 const char *name = NULL;
68
69 if (!event_class) {
70 goto end;
71 }
72
73 name = g_quark_to_string(event_class->name);
74end:
75 return name;
76}
77
78int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
79{
80 int64_t ret;
81
82 if (!event_class || !event_class->id_set) {
83 ret = -1;
84 goto end;
85 }
86
87 ret = (int64_t) event_class->id;
88end:
89 return ret;
90}
91
92int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
93 uint32_t id)
94{
95 int ret = 0;
96
97 if (!event_class) {
98 ret = -1;
99 goto end;
100 }
101
102 if (event_class->stream_class) {
103 /*
104 * We don't allow changing the id if the event class has already
105 * been added to a stream class.
106 */
107 ret = -1;
108 goto end;
109 }
110
111 event_class->id = id;
112 event_class->id_set = 1;
113end:
114 return ret;
115}
116
117struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
118 struct bt_ctf_event_class *event_class)
119{
120 struct bt_ctf_stream_class *stream_class = NULL;
121
122 if (!event_class) {
123 goto end;
124 }
125
126 stream_class = event_class->stream_class;
127 bt_ctf_stream_class_get(stream_class);
128end:
129 return stream_class;
130}
131
273b65be
JG
132int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
133 struct bt_ctf_field_type *type,
134 const char *name)
135{
136 int ret = 0;
137
654c1444 138 if (!event_class || !type || bt_ctf_validate_identifier(name) ||
273b65be
JG
139 event_class->frozen) {
140 ret = -1;
141 goto end;
142 }
143
144 if (!event_class->fields) {
145 event_class->fields = bt_ctf_field_type_structure_create();
146 if (!event_class->fields) {
147 ret = -1;
148 goto end;
149 }
150 }
151
152 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
153 type, name);
154end:
155 return ret;
156}
157
074ee56d 158int bt_ctf_event_class_get_field_count(
2f100782
JG
159 struct bt_ctf_event_class *event_class)
160{
074ee56d 161 int ret;
2f100782
JG
162
163 if (!event_class) {
164 ret = -1;
165 goto end;
166 }
167
168 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
169end:
170 return ret;
171}
172
173int bt_ctf_event_class_get_field(struct bt_ctf_event_class *event_class,
174 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 175 int index)
2f100782
JG
176{
177 int ret;
178
074ee56d 179 if (!event_class || index < 0) {
2f100782
JG
180 ret = -1;
181 goto end;
182 }
183
184 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
185 field_name, field_type, index);
186end:
187 return ret;
188}
189
190struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
191 struct bt_ctf_event_class *event_class, const char *name)
192{
193 GQuark name_quark;
194 struct bt_ctf_field_type *field_type = NULL;
195
196 if (!event_class || !name) {
197 goto end;
198 }
199
200 name_quark = g_quark_try_string(name);
201 if (!name_quark) {
202 goto end;
203 }
204
205 /*
206 * No need to increment field_type's reference count since getting it
207 * from the structure already does.
208 */
209 field_type = bt_ctf_field_type_structure_get_field_type_by_name(
210 event_class->fields, name);
211end:
212 return field_type;
213}
214
f655a84d
JG
215struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
216 struct bt_ctf_event_class *event_class)
217{
218 struct bt_ctf_field_type *context_type = NULL;
219
220 if (!event_class || !event_class->context) {
221 goto end;
222 }
223
224 bt_ctf_field_type_get(event_class->context);
225 context_type = event_class->context;
226end:
227 return context_type;
228}
229
230int bt_ctf_event_class_set_context_type(
231 struct bt_ctf_event_class *event_class,
232 struct bt_ctf_field_type *context)
233{
234 int ret = 0;
235
236 if (!event_class || !context || event_class->frozen) {
237 ret = -1;
238 goto end;
239 }
240
241 if (bt_ctf_field_type_get_type_id(context) != CTF_TYPE_STRUCT) {
242 ret = -1;
243 goto end;
244 }
245
246 bt_ctf_field_type_get(context);
247 bt_ctf_field_type_put(event_class->context);
248 event_class->context = context;
249end:
250 return ret;
251
252}
253
273b65be
JG
254void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
255{
256 if (!event_class) {
257 return;
258 }
259
260 bt_ctf_ref_get(&event_class->ref_count);
261}
262
263void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
264{
265 if (!event_class) {
266 return;
267 }
268
269 bt_ctf_ref_put(&event_class->ref_count, bt_ctf_event_class_destroy);
270}
271
272struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
273{
274 struct bt_ctf_event *event = NULL;
275
276 if (!event_class) {
277 goto end;
278 }
279
280 event = g_new0(struct bt_ctf_event, 1);
281 if (!event) {
282 goto end;
283 }
284
285 bt_ctf_ref_init(&event->ref_count);
286 bt_ctf_event_class_get(event_class);
287 bt_ctf_event_class_freeze(event_class);
288 event->event_class = event_class;
f655a84d
JG
289 if (event_class->context) {
290 event->context_payload = bt_ctf_field_create(
291 event_class->context);
292 }
273b65be
JG
293 event->fields_payload = bt_ctf_field_create(event_class->fields);
294end:
295 return event;
296}
297
2f100782
JG
298struct bt_ctf_event_class *bt_ctf_event_get_class(struct bt_ctf_event *event)
299{
300 struct bt_ctf_event_class *event_class = NULL;
301
302 if (!event) {
303 goto end;
304 }
305
306 event_class = event->event_class;
307 bt_ctf_event_class_get(event_class);
308end:
309 return event_class;
310}
311
312struct bt_ctf_clock *bt_ctf_event_get_clock(struct bt_ctf_event *event)
313{
314 struct bt_ctf_clock *clock = NULL;
315 struct bt_ctf_event_class *event_class;
316 struct bt_ctf_stream_class *stream_class;
317
318 if (!event) {
319 goto end;
320 }
321
322 event_class = bt_ctf_event_get_class(event);
323 if (!event_class) {
324 goto end;
325 }
326
327 stream_class = bt_ctf_event_class_get_stream_class(event_class);
328 if (!stream_class) {
329 goto error_put_event_class;
330 }
331
332 clock = bt_ctf_stream_class_get_clock(stream_class);
333 if (!clock) {
334 goto error_put_stream_class;
335 }
336
337error_put_stream_class:
338 bt_ctf_stream_class_put(stream_class);
339error_put_event_class:
340 bt_ctf_event_class_put(event_class);
341end:
342 return clock;
343}
344
273b65be
JG
345int bt_ctf_event_set_payload(struct bt_ctf_event *event,
346 const char *name,
347 struct bt_ctf_field *value)
348{
349 int ret = 0;
350
654c1444 351 if (!event || !value || bt_ctf_validate_identifier(name)) {
273b65be
JG
352 ret = -1;
353 goto end;
354 }
355
356 ret = bt_ctf_field_structure_set_field(event->fields_payload,
357 name, value);
358end:
359 return ret;
360}
361
362
363struct bt_ctf_field *bt_ctf_event_get_payload(struct bt_ctf_event *event,
364 const char *name)
365{
366 struct bt_ctf_field *field = NULL;
367
368 if (!event || !name) {
369 goto end;
370 }
371
372 field = bt_ctf_field_structure_get_field(event->fields_payload, name);
373end:
374 return field;
375}
376
2f100782 377struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
074ee56d 378 struct bt_ctf_event *event, int index)
2f100782
JG
379{
380 struct bt_ctf_field *field = NULL;
381
074ee56d 382 if (!event || index < 0) {
2f100782
JG
383 goto end;
384 }
385
386 field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
387 index);
388end:
389 return field;
390}
391
f655a84d
JG
392struct bt_ctf_field *bt_ctf_event_get_event_context(
393 struct bt_ctf_event *event)
394{
395 struct bt_ctf_field *context = NULL;
396
397 if (!event || !event->context_payload) {
398 goto end;
399 }
400
401 context = event->context_payload;
402 bt_ctf_field_get(context);
403end:
404 return context;
405}
406
407int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
408 struct bt_ctf_field *context)
409{
410 int ret = 0;
411 struct bt_ctf_field_type *field_type = NULL;
412
413 if (!event || !context) {
414 ret = -1;
415 goto end;
416 }
417
418 field_type = bt_ctf_field_get_type(context);
419 if (field_type != event->event_class->context) {
420 ret = -1;
421 goto end;
422 }
423
424 bt_ctf_field_get(context);
425 bt_ctf_field_put(event->context_payload);
426 event->context_payload = context;
427end:
428 if (field_type) {
429 bt_ctf_field_type_put(field_type);
430 }
431 return ret;
432}
433
273b65be
JG
434void bt_ctf_event_get(struct bt_ctf_event *event)
435{
436 if (!event) {
437 return;
438 }
439
440 bt_ctf_ref_get(&event->ref_count);
441}
442
443void bt_ctf_event_put(struct bt_ctf_event *event)
444{
445 if (!event) {
446 return;
447 }
448
449 bt_ctf_ref_put(&event->ref_count, bt_ctf_event_destroy);
450}
451
452static
453void bt_ctf_event_class_destroy(struct bt_ctf_ref *ref)
454{
455 struct bt_ctf_event_class *event_class;
456
457 if (!ref) {
458 return;
459 }
460
2f100782
JG
461 /*
462 * Don't call put() on the stream class. See comment in
463 * bt_ctf_event_class_set_stream_class for explanation.
464 */
273b65be 465 event_class = container_of(ref, struct bt_ctf_event_class, ref_count);
f655a84d
JG
466 if (event_class->context) {
467 bt_ctf_field_type_put(event_class->context);
468 }
469 if (event_class->fields) {
470 bt_ctf_field_type_put(event_class->fields);
471 }
273b65be
JG
472 g_free(event_class);
473}
474
475static
476void bt_ctf_event_destroy(struct bt_ctf_ref *ref)
477{
478 struct bt_ctf_event *event;
479
480 if (!ref) {
481 return;
482 }
483
484 event = container_of(ref, struct bt_ctf_event,
485 ref_count);
f655a84d
JG
486 if (event->event_class) {
487 bt_ctf_event_class_put(event->event_class);
488 }
489 if (event->context_payload) {
490 bt_ctf_field_put(event->context_payload);
491 }
492 if (event->fields_payload) {
493 bt_ctf_field_put(event->fields_payload);
494 }
273b65be
JG
495 g_free(event);
496}
497
498BT_HIDDEN
499void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
500{
501 assert(event_class);
502 event_class->frozen = 1;
503 bt_ctf_field_type_freeze(event_class->context);
504 bt_ctf_field_type_freeze(event_class->fields);
505}
506
507BT_HIDDEN
2f100782
JG
508int bt_ctf_event_class_set_stream_class(struct bt_ctf_event_class *event_class,
509 struct bt_ctf_stream_class *stream_class)
273b65be
JG
510{
511 int ret = 0;
512
2f100782 513 if (!event_class) {
273b65be
JG
514 ret = -1;
515 goto end;
516 }
517
2f100782
JG
518 /* Allow a NULL stream_class to unset the current stream_class */
519 if (stream_class && event_class->stream_class) {
273b65be
JG
520 ret = -1;
521 goto end;
522 }
523
2f100782
JG
524 event_class->stream_class = stream_class;
525 /*
526 * We don't get() the stream_class since doing so would introduce
527 * a circular ownership between event classes and stream classes.
528 *
529 * A stream class will always unset itself from its events before
530 * being destroyed. This ensures that a user won't get a pointer
531 * to a stale stream class instance from an event class.
532 */
273b65be
JG
533end:
534 return ret;
535}
536
537BT_HIDDEN
538int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
539 struct metadata_context *context)
540{
541 int ret = 0;
2f100782 542 int64_t stream_id;
273b65be
JG
543
544 assert(event_class);
545 assert(context);
2f100782
JG
546 stream_id = bt_ctf_stream_class_get_id(event_class->stream_class);
547 if (stream_id < 0) {
548 ret = -1;
549 goto end;
550 }
551
273b65be
JG
552 context->current_indentation_level = 1;
553 g_string_assign(context->field_name, "");
de876b7f 554 g_string_append_printf(context->string, "event {\n\tname = \"%s\";\n\tid = %u;\n\tstream_id = %" PRId64 ";\n",
273b65be
JG
555 g_quark_to_string(event_class->name),
556 event_class->id,
2f100782 557 stream_id);
273b65be
JG
558
559 if (event_class->context) {
560 g_string_append(context->string, "\tcontext := ");
561 ret = bt_ctf_field_type_serialize(event_class->context,
562 context);
563 if (ret) {
564 goto end;
565 }
566 g_string_append(context->string, ";\n");
567 }
568
569 if (event_class->fields) {
570 g_string_append(context->string, "\tfields := ");
571 ret = bt_ctf_field_type_serialize(event_class->fields, context);
572 if (ret) {
573 goto end;
574 }
575 g_string_append(context->string, ";\n");
576 }
577
578 g_string_append(context->string, "};\n\n");
579end:
580 context->current_indentation_level = 0;
581 return ret;
582}
583
c35a1669
JG
584void bt_ctf_event_class_set_native_byte_order(
585 struct bt_ctf_event_class *event_class,
586 int byte_order)
587{
588 if (!event_class) {
589 return;
590 }
591
592 bt_ctf_field_type_set_native_byte_order(event_class->context,
593 byte_order);
594 bt_ctf_field_type_set_native_byte_order(event_class->fields,
595 byte_order);
596}
597
273b65be
JG
598BT_HIDDEN
599int bt_ctf_event_validate(struct bt_ctf_event *event)
600{
601 /* Make sure each field's payload has been set */
602 int ret;
603
604 assert(event);
605 ret = bt_ctf_field_validate(event->fields_payload);
606 if (ret) {
607 goto end;
608 }
609
610 if (event->event_class->context) {
611 ret = bt_ctf_field_validate(event->context_payload);
612 }
613end:
614 return ret;
615}
616
617BT_HIDDEN
618int bt_ctf_event_serialize(struct bt_ctf_event *event,
619 struct ctf_stream_pos *pos)
620{
621 int ret = 0;
622
623 assert(event);
624 assert(pos);
625 if (event->context_payload) {
626 ret = bt_ctf_field_serialize(event->context_payload, pos);
627 if (ret) {
628 goto end;
629 }
630 }
631
632 if (event->fields_payload) {
633 ret = bt_ctf_field_serialize(event->fields_payload, pos);
634 if (ret) {
635 goto end;
636 }
637 }
638end:
639 return ret;
640}
641
642BT_HIDDEN
643int bt_ctf_event_set_timestamp(struct bt_ctf_event *event,
644 uint64_t timestamp)
645{
646 int ret = 0;
647
648 assert(event);
649 if (event->timestamp) {
650 ret = -1;
651 goto end;
652 }
653
654 event->timestamp = timestamp;
655end:
656 return ret;
657}
658
659BT_HIDDEN
660uint64_t bt_ctf_event_get_timestamp(struct bt_ctf_event *event)
661{
662 assert(event);
663 return event->timestamp;
664}
This page took 0.050539 seconds and 4 git commands to generate.