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