Unify reference counting using a common bt_object base
[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>
83509119 39#include <babeltrace/ref.h>
44e0a4f5 40#include <babeltrace/ctf-ir/attributes-internal.h>
273b65be
JG
41#include <babeltrace/compiler.h>
42
43static
83509119 44void bt_ctf_event_class_destroy(struct bt_object *obj);
273b65be 45static
83509119 46void bt_ctf_event_destroy(struct bt_object *obj);
662e778c
JG
47static
48int set_integer_field_value(struct bt_ctf_field *field, uint64_t value);
273b65be
JG
49
50struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
51{
b8248cc0 52 int ret;
dac5c838 53 struct bt_value *obj = NULL;
273b65be
JG
54 struct bt_ctf_event_class *event_class = NULL;
55
654c1444 56 if (bt_ctf_validate_identifier(name)) {
b8248cc0 57 goto error;
273b65be
JG
58 }
59
60 event_class = g_new0(struct bt_ctf_event_class, 1);
61 if (!event_class) {
b8248cc0 62 goto error;
273b65be
JG
63 }
64
83509119 65 bt_object_init(event_class, bt_ctf_event_class_destroy);
c5a9aa19
JG
66 event_class->fields = bt_ctf_field_type_structure_create();
67 if (!event_class->fields) {
b8248cc0 68 goto error;
c5a9aa19
JG
69 }
70
b8248cc0
PP
71 event_class->attributes = bt_ctf_attributes_create();
72 if (!event_class->attributes) {
73 goto error;
74 }
75
dac5c838 76 obj = bt_value_integer_create_init(-1);
b8248cc0
PP
77 if (!obj) {
78 goto error;
79 }
80
81 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
82 "id", obj);
83 if (ret) {
84 goto error;
85 }
86
83509119 87 BT_PUT(obj);
b8248cc0 88
dac5c838 89 obj = bt_value_string_create_init(name);
b8248cc0
PP
90 if (!obj) {
91 goto error;
92 }
93
94 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
95 "name", obj);
96 if (ret) {
97 goto error;
98 }
99
83509119 100 BT_PUT(obj);
b8248cc0 101
273b65be 102 return event_class;
b8248cc0
PP
103
104error:
83509119
JG
105 BT_PUT(event_class);
106 BT_PUT(obj);
107 return event_class;
273b65be
JG
108}
109
2f100782
JG
110const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
111{
dac5c838 112 struct bt_value *obj = NULL;
2f100782
JG
113 const char *name = NULL;
114
115 if (!event_class) {
116 goto end;
117 }
118
b8248cc0
PP
119 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
120 BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
121 if (!obj) {
122 goto end;
123 }
124
dac5c838 125 if (bt_value_string_get(obj, &name)) {
b8248cc0
PP
126 name = NULL;
127 }
128
2f100782 129end:
83509119 130 BT_PUT(obj);
2f100782
JG
131 return name;
132}
133
134int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
135{
dac5c838 136 struct bt_value *obj = NULL;
9ea90c02 137 int64_t ret = 0;
2f100782 138
b8248cc0
PP
139 if (!event_class) {
140 ret = -1;
141 goto end;
142 }
143
144 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
145 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
146 if (!obj) {
147 goto end;
148 }
149
dac5c838 150 if (bt_value_integer_get(obj, &ret)) {
b8248cc0
PP
151 ret = -1;
152 }
153
154 if (ret < 0) {
155 /* means ID is not set */
2f100782
JG
156 ret = -1;
157 goto end;
158 }
159
2f100782 160end:
83509119 161 BT_PUT(obj);
2f100782
JG
162 return ret;
163}
164
165int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
166 uint32_t id)
167{
168 int ret = 0;
dac5c838 169 struct bt_value *obj = NULL;
2f100782
JG
170
171 if (!event_class) {
172 ret = -1;
173 goto end;
174 }
175
176 if (event_class->stream_class) {
177 /*
178 * We don't allow changing the id if the event class has already
179 * been added to a stream class.
180 */
181 ret = -1;
182 goto end;
183 }
184
b8248cc0
PP
185 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
186 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
187 if (!obj) {
188 goto end;
189 }
190
dac5c838 191 if (bt_value_integer_set(obj, id)) {
b8248cc0
PP
192 ret = -1;
193 goto end;
194 }
195
196end:
83509119 197 BT_PUT(obj);
b8248cc0
PP
198 return ret;
199}
200
201int bt_ctf_event_class_set_attribute(
202 struct bt_ctf_event_class *event_class, const char *name,
dac5c838 203 struct bt_value *value)
b8248cc0
PP
204{
205 int ret = 0;
206
207 if (!event_class || !name || !value || event_class->frozen) {
208 ret = -1;
209 goto end;
210 }
211
212 if (!strcmp(name, "id") || !strcmp(name, "loglevel")) {
dac5c838 213 if (!bt_value_is_integer(value)) {
b8248cc0
PP
214 ret = -1;
215 goto end;
216 }
217 } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri")) {
dac5c838 218 if (!bt_value_is_string(value)) {
b8248cc0
PP
219 ret = -1;
220 goto end;
221 }
222 } else {
223 /* unknown attribute */
224 ret = -1;
225 goto end;
226 }
227
228 /* "id" special case: >= 0 */
229 if (!strcmp(name, "id")) {
230 int64_t val;
231
dac5c838 232 ret = bt_value_integer_get(value, &val);
b8248cc0
PP
233
234 if (ret) {
235 goto end;
236 }
237
238 if (val < 0) {
239 ret = -1;
240 goto end;
241 }
242 }
243
244 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
245 name, value);
246
2f100782
JG
247end:
248 return ret;
249}
250
b8248cc0
PP
251int bt_ctf_event_class_get_attribute_count(
252 struct bt_ctf_event_class *event_class)
253{
254 int ret = 0;
255
256 if (!event_class) {
257 ret = -1;
258 goto end;
259 }
260
261 ret = bt_ctf_attributes_get_count(event_class->attributes);
262
263end:
264 return ret;
265}
266
267const char *
268bt_ctf_event_class_get_attribute_name(
269 struct bt_ctf_event_class *event_class, int index)
270{
271 const char *ret;
272
273 if (!event_class) {
274 ret = NULL;
275 goto end;
276 }
277
278 ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
279
280end:
281 return ret;
282}
283
dac5c838 284struct bt_value *
b8248cc0
PP
285bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
286 int index)
287{
dac5c838 288 struct bt_value *ret;
b8248cc0
PP
289
290 if (!event_class) {
291 ret = NULL;
292 goto end;
293 }
294
295 ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
296
297end:
298 return ret;
299}
300
dac5c838 301struct bt_value *
b8248cc0
PP
302bt_ctf_event_class_get_attribute_value_by_name(
303 struct bt_ctf_event_class *event_class, const char *name)
304{
dac5c838 305 struct bt_value *ret;
b8248cc0
PP
306
307 if (!event_class || !name) {
308 ret = NULL;
309 goto end;
310 }
311
312 ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
313 name);
314
315end:
316 return ret;
317
318}
319
2f100782
JG
320struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
321 struct bt_ctf_event_class *event_class)
322{
323 struct bt_ctf_stream_class *stream_class = NULL;
324
325 if (!event_class) {
326 goto end;
327 }
328
329 stream_class = event_class->stream_class;
83509119 330 bt_get(stream_class);
2f100782
JG
331end:
332 return stream_class;
333}
334
c5a9aa19
JG
335struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
336 struct bt_ctf_event_class *event_class)
337{
338 struct bt_ctf_field_type *payload = NULL;
339
340 if (!event_class) {
341 goto end;
342 }
343
83509119 344 bt_get(event_class->fields);
c5a9aa19
JG
345 payload = event_class->fields;
346end:
347 return payload;
348}
349
350int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
351 struct bt_ctf_field_type *payload)
352{
353 int ret = 0;
354
d2127f80
JG
355 if (!event_class || !payload ||
356 bt_ctf_field_type_get_type_id(payload) != CTF_TYPE_STRUCT) {
c5a9aa19
JG
357 ret = -1;
358 goto end;
359 }
360
83509119
JG
361 bt_get(payload);
362 bt_put(event_class->fields);
c5a9aa19
JG
363 event_class->fields = payload;
364end:
365 return ret;
366}
367
273b65be
JG
368int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
369 struct bt_ctf_field_type *type,
370 const char *name)
371{
372 int ret = 0;
373
654c1444 374 if (!event_class || !type || bt_ctf_validate_identifier(name) ||
273b65be
JG
375 event_class->frozen) {
376 ret = -1;
377 goto end;
378 }
379
c5a9aa19
JG
380 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
381 CTF_TYPE_STRUCT) {
382 ret = -1;
383 goto end;
273b65be
JG
384 }
385
386 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
387 type, name);
388end:
389 return ret;
390}
391
074ee56d 392int bt_ctf_event_class_get_field_count(
2f100782
JG
393 struct bt_ctf_event_class *event_class)
394{
074ee56d 395 int ret;
2f100782
JG
396
397 if (!event_class) {
398 ret = -1;
399 goto end;
400 }
401
c5a9aa19
JG
402 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
403 CTF_TYPE_STRUCT) {
404 ret = -1;
405 goto end;
406 }
407
2f100782
JG
408 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
409end:
410 return ret;
411}
412
413int bt_ctf_event_class_get_field(struct bt_ctf_event_class *event_class,
414 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 415 int index)
2f100782
JG
416{
417 int ret;
418
074ee56d 419 if (!event_class || index < 0) {
2f100782
JG
420 ret = -1;
421 goto end;
422 }
423
c5a9aa19
JG
424 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
425 CTF_TYPE_STRUCT) {
426 ret = -1;
427 goto end;
428 }
429
2f100782
JG
430 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
431 field_name, field_type, index);
432end:
433 return ret;
434}
435
436struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
437 struct bt_ctf_event_class *event_class, const char *name)
438{
439 GQuark name_quark;
440 struct bt_ctf_field_type *field_type = NULL;
441
442 if (!event_class || !name) {
443 goto end;
444 }
445
c5a9aa19
JG
446 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
447 CTF_TYPE_STRUCT) {
448 goto end;
449 }
450
2f100782
JG
451 name_quark = g_quark_try_string(name);
452 if (!name_quark) {
453 goto end;
454 }
455
456 /*
457 * No need to increment field_type's reference count since getting it
458 * from the structure already does.
459 */
460 field_type = bt_ctf_field_type_structure_get_field_type_by_name(
461 event_class->fields, name);
462end:
463 return field_type;
464}
465
f655a84d
JG
466struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
467 struct bt_ctf_event_class *event_class)
468{
469 struct bt_ctf_field_type *context_type = NULL;
470
471 if (!event_class || !event_class->context) {
472 goto end;
473 }
474
83509119 475 bt_get(event_class->context);
f655a84d
JG
476 context_type = event_class->context;
477end:
478 return context_type;
479}
480
481int bt_ctf_event_class_set_context_type(
482 struct bt_ctf_event_class *event_class,
483 struct bt_ctf_field_type *context)
484{
485 int ret = 0;
486
487 if (!event_class || !context || event_class->frozen) {
488 ret = -1;
489 goto end;
490 }
491
492 if (bt_ctf_field_type_get_type_id(context) != CTF_TYPE_STRUCT) {
493 ret = -1;
494 goto end;
495 }
496
83509119
JG
497 bt_get(context);
498 bt_put(event_class->context);
f655a84d
JG
499 event_class->context = context;
500end:
501 return ret;
502
503}
504
273b65be
JG
505void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
506{
83509119 507 bt_get(event_class);
273b65be
JG
508}
509
510void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
511{
83509119 512 bt_put(event_class);
273b65be
JG
513}
514
29664b2a
PP
515BT_HIDDEN
516int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
517 uint32_t stream_id)
518{
519 int ret = 0;
dac5c838 520 struct bt_value *obj;
29664b2a 521
dac5c838 522 obj = bt_value_integer_create_init(stream_id);
29664b2a
PP
523
524 if (!obj) {
525 ret = -1;
526 goto end;
527 }
528
529 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
530 "stream_id", obj);
531
532end:
83509119 533 BT_PUT(obj);
29664b2a
PP
534 return ret;
535}
536
273b65be
JG
537struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
538{
539 struct bt_ctf_event *event = NULL;
540
541 if (!event_class) {
542 goto end;
543 }
544
662e778c
JG
545 /*
546 * The event class does not keep ownership of the stream class to
547 * which it as been added. Therefore, it can't assume it has been
548 * set. However, we disallow the creation of an event if its
549 * associated stream class has been reclaimed.
550 */
551 if (!event_class->stream_class) {
b8248cc0 552 goto end;
662e778c
JG
553 }
554 assert(event_class->stream_class->event_header_type);
b8248cc0
PP
555 event = g_new0(struct bt_ctf_event, 1);
556 if (!event) {
557 goto end;
558 }
559
83509119
JG
560 bt_object_init(event, bt_ctf_event_destroy);
561 bt_get(event_class);
b8248cc0
PP
562 bt_ctf_event_class_freeze(event_class);
563 event->event_class = event_class;
564
662e778c
JG
565 event->event_header = bt_ctf_field_create(
566 event_class->stream_class->event_header_type);
567 if (!event->event_header) {
83509119 568 goto error;
662e778c 569 }
f655a84d
JG
570 if (event_class->context) {
571 event->context_payload = bt_ctf_field_create(
572 event_class->context);
662e778c 573 if (!event->context_payload) {
83509119 574 goto error;
662e778c 575 }
f655a84d 576 }
273b65be 577 event->fields_payload = bt_ctf_field_create(event_class->fields);
662e778c 578 if (!event->fields_payload) {
83509119 579 goto error;
662e778c
JG
580 }
581
582 /*
583 * Freeze the stream class since the event header must not be changed
584 * anymore.
585 */
586 bt_ctf_stream_class_freeze(event_class->stream_class);
273b65be
JG
587end:
588 return event;
83509119
JG
589error:
590 BT_PUT(event);
591 return event;
273b65be
JG
592}
593
2f100782
JG
594struct bt_ctf_event_class *bt_ctf_event_get_class(struct bt_ctf_event *event)
595{
596 struct bt_ctf_event_class *event_class = NULL;
597
598 if (!event) {
599 goto end;
600 }
601
602 event_class = event->event_class;
83509119 603 bt_get(event_class);
2f100782
JG
604end:
605 return event_class;
606}
607
8e5003bb
JG
608struct bt_ctf_stream *bt_ctf_event_get_stream(struct bt_ctf_event *event)
609{
610 struct bt_ctf_stream *stream = NULL;
611
612 if (!event) {
613 goto end;
614 }
615
616 stream = event->stream;
83509119 617 bt_get(stream);
8e5003bb
JG
618end:
619 return stream;
620}
621
2f100782
JG
622struct bt_ctf_clock *bt_ctf_event_get_clock(struct bt_ctf_event *event)
623{
624 struct bt_ctf_clock *clock = NULL;
625 struct bt_ctf_event_class *event_class;
626 struct bt_ctf_stream_class *stream_class;
627
628 if (!event) {
629 goto end;
630 }
631
632 event_class = bt_ctf_event_get_class(event);
633 if (!event_class) {
634 goto end;
635 }
636
637 stream_class = bt_ctf_event_class_get_stream_class(event_class);
638 if (!stream_class) {
639 goto error_put_event_class;
640 }
641
642 clock = bt_ctf_stream_class_get_clock(stream_class);
643 if (!clock) {
644 goto error_put_stream_class;
645 }
646
647error_put_stream_class:
83509119 648 bt_put(stream_class);
2f100782 649error_put_event_class:
83509119 650 bt_put(event_class);
2f100782
JG
651end:
652 return clock;
653}
654
273b65be
JG
655int bt_ctf_event_set_payload(struct bt_ctf_event *event,
656 const char *name,
c5a9aa19 657 struct bt_ctf_field *payload)
273b65be
JG
658{
659 int ret = 0;
660
c5a9aa19 661 if (!event || !payload) {
273b65be
JG
662 ret = -1;
663 goto end;
664 }
665
c5a9aa19
JG
666 if (name) {
667 ret = bt_ctf_field_structure_set_field(event->fields_payload,
668 name, payload);
669 } else {
670 struct bt_ctf_field_type *payload_type;
671
672 payload_type = bt_ctf_field_get_type(payload);
673 if (payload_type == event->event_class->fields) {
83509119
JG
674 bt_put(event->fields_payload);
675 bt_get(payload);
c5a9aa19
JG
676 event->fields_payload = payload;
677 } else {
678 ret = -1;
679 }
680
83509119 681 bt_put(payload_type);
c5a9aa19 682 }
273b65be
JG
683end:
684 return ret;
685}
686
71362d53
PP
687struct bt_ctf_field *bt_ctf_event_get_payload_field(struct bt_ctf_event *event)
688{
689 struct bt_ctf_field *payload = NULL;
690
691 if (!event || !event->fields_payload) {
692 goto end;
693 }
694
695 payload = event->fields_payload;
83509119 696 bt_get(payload);
71362d53
PP
697end:
698 return payload;
699}
273b65be 700
e5e6eb3a
JG
701int bt_ctf_event_set_payload_field(struct bt_ctf_event *event,
702 struct bt_ctf_field *payload)
703{
704 int ret = 0;
705 struct bt_ctf_field_type *payload_type = NULL;
706
707 if (!event || !payload) {
708 ret = -1;
709 goto end;
710 }
711
712 payload_type = bt_ctf_field_get_type(payload);
713 if (!payload_type) {
714 ret = -1;
715 goto end;
716 }
717
718 if (bt_ctf_field_type_get_type_id(payload_type) != CTF_TYPE_STRUCT) {
719 ret = -1;
720 goto end;
721 }
722
83509119
JG
723 bt_get(payload);
724 bt_put(event->fields_payload);
e5e6eb3a
JG
725 event->fields_payload = payload;
726
727end:
83509119 728 bt_put(payload_type);
e5e6eb3a
JG
729 return ret;
730}
731
273b65be
JG
732struct bt_ctf_field *bt_ctf_event_get_payload(struct bt_ctf_event *event,
733 const char *name)
734{
735 struct bt_ctf_field *field = NULL;
736
c5a9aa19 737 if (!event) {
273b65be
JG
738 goto end;
739 }
740
c5a9aa19
JG
741 if (name) {
742 field = bt_ctf_field_structure_get_field(event->fields_payload,
743 name);
744 } else {
745 field = event->fields_payload;
83509119 746 bt_get(field);
c5a9aa19 747 }
273b65be
JG
748end:
749 return field;
750}
751
2f100782 752struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
074ee56d 753 struct bt_ctf_event *event, int index)
2f100782
JG
754{
755 struct bt_ctf_field *field = NULL;
756
074ee56d 757 if (!event || index < 0) {
2f100782
JG
758 goto end;
759 }
760
761 field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
762 index);
763end:
764 return field;
765}
766
286a2840 767struct bt_ctf_field *bt_ctf_event_get_header(
662e778c
JG
768 struct bt_ctf_event *event)
769{
770 struct bt_ctf_field *header = NULL;
771
772 if (!event || !event->event_header) {
773 goto end;
774 }
775
776 header = event->event_header;
83509119 777 bt_get(header);
662e778c
JG
778end:
779 return header;
780}
781
286a2840 782int bt_ctf_event_set_header(struct bt_ctf_event *event,
662e778c
JG
783 struct bt_ctf_field *header)
784{
785 int ret = 0;
786 struct bt_ctf_field_type *field_type = NULL;
787
788 if (!event || !header) {
789 ret = -1;
790 goto end;
791 }
792
793 /* Could be NULL since an event class doesn't own a stream class */
794 if (!event->event_class->stream_class) {
795 ret = -1;
796 goto end;
797 }
798
799 /*
800 * Ensure the provided header's type matches the one registered to the
801 * stream class.
802 */
803 field_type = bt_ctf_field_get_type(header);
804 if (field_type != event->event_class->stream_class->event_header_type) {
805 ret = -1;
806 goto end;
807 }
808
83509119
JG
809 bt_get(header);
810 bt_put(event->event_header);
662e778c
JG
811 event->event_header = header;
812end:
83509119 813 bt_put(field_type);
662e778c
JG
814 return ret;
815}
816
f655a84d
JG
817struct bt_ctf_field *bt_ctf_event_get_event_context(
818 struct bt_ctf_event *event)
819{
820 struct bt_ctf_field *context = NULL;
821
822 if (!event || !event->context_payload) {
823 goto end;
824 }
825
826 context = event->context_payload;
83509119 827 bt_get(context);
f655a84d
JG
828end:
829 return context;
830}
831
832int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
833 struct bt_ctf_field *context)
834{
835 int ret = 0;
836 struct bt_ctf_field_type *field_type = NULL;
837
838 if (!event || !context) {
839 ret = -1;
840 goto end;
841 }
842
843 field_type = bt_ctf_field_get_type(context);
844 if (field_type != event->event_class->context) {
845 ret = -1;
846 goto end;
847 }
848
83509119
JG
849 bt_get(context);
850 bt_put(event->context_payload);
f655a84d
JG
851 event->context_payload = context;
852end:
83509119 853 bt_put(field_type);
f655a84d
JG
854 return ret;
855}
856
273b65be
JG
857void bt_ctf_event_get(struct bt_ctf_event *event)
858{
83509119 859 bt_get(event);
273b65be
JG
860}
861
862void bt_ctf_event_put(struct bt_ctf_event *event)
863{
83509119 864 bt_put(event);
273b65be
JG
865}
866
867static
83509119 868void bt_ctf_event_class_destroy(struct bt_object *obj)
273b65be
JG
869{
870 struct bt_ctf_event_class *event_class;
273b65be 871
2f100782
JG
872 /*
873 * Don't call put() on the stream class. See comment in
874 * bt_ctf_event_class_set_stream_class for explanation.
875 */
83509119
JG
876 event_class = container_of(obj, struct bt_ctf_event_class, base);
877 bt_ctf_attributes_destroy(event_class->attributes);
878 bt_put(event_class->context);
879 bt_put(event_class->fields);
273b65be
JG
880 g_free(event_class);
881}
882
883static
83509119 884void bt_ctf_event_destroy(struct bt_object *obj)
273b65be
JG
885{
886 struct bt_ctf_event *event;
887
83509119
JG
888 event = container_of(obj, struct bt_ctf_event, base);
889 bt_put(event->event_class);
890 bt_put(event->event_header);
891 bt_put(event->context_payload);
892 bt_put(event->fields_payload);
273b65be
JG
893 g_free(event);
894}
895
662e778c
JG
896static
897int set_integer_field_value(struct bt_ctf_field* field, uint64_t value)
898{
899 int ret = 0;
900 struct bt_ctf_field_type *field_type = NULL;
901
902 if (!field) {
903 ret = -1;
904 goto end;
905 }
906
907 if (!bt_ctf_field_validate(field)) {
908 /* Payload already set, skip! (not an error) */
909 goto end;
910 }
911
912 field_type = bt_ctf_field_get_type(field);
913 assert(field_type);
914
915 if (bt_ctf_field_type_get_type_id(field_type) != CTF_TYPE_INTEGER) {
916 /* Not an integer and the value is unset, error. */
917 ret = -1;
918 goto end;
919 }
920
921 if (bt_ctf_field_type_integer_get_signed(field_type)) {
922 ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value);
923 if (ret) {
924 /* Value is out of range, error. */
925 goto end;
926 }
927 } else {
928 ret = bt_ctf_field_unsigned_integer_set_value(field, value);
929 if (ret) {
930 /* Value is out of range, error. */
931 goto end;
932 }
933 }
934end:
83509119 935 bt_put(field_type);
662e778c
JG
936 return ret;
937}
938
273b65be
JG
939BT_HIDDEN
940void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
941{
942 assert(event_class);
943 event_class->frozen = 1;
944 bt_ctf_field_type_freeze(event_class->context);
945 bt_ctf_field_type_freeze(event_class->fields);
b8248cc0 946 bt_ctf_attributes_freeze(event_class->attributes);
273b65be
JG
947}
948
949BT_HIDDEN
2f100782
JG
950int bt_ctf_event_class_set_stream_class(struct bt_ctf_event_class *event_class,
951 struct bt_ctf_stream_class *stream_class)
273b65be
JG
952{
953 int ret = 0;
954
2f100782 955 if (!event_class) {
273b65be
JG
956 ret = -1;
957 goto end;
958 }
959
2f100782
JG
960 /* Allow a NULL stream_class to unset the current stream_class */
961 if (stream_class && event_class->stream_class) {
273b65be
JG
962 ret = -1;
963 goto end;
964 }
965
2f100782
JG
966 event_class->stream_class = stream_class;
967 /*
968 * We don't get() the stream_class since doing so would introduce
969 * a circular ownership between event classes and stream classes.
970 *
971 * A stream class will always unset itself from its events before
972 * being destroyed. This ensures that a user won't get a pointer
973 * to a stale stream class instance from an event class.
974 */
273b65be
JG
975end:
976 return ret;
977}
978
979BT_HIDDEN
980int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
981 struct metadata_context *context)
982{
b8248cc0
PP
983 int i;
984 int count;
273b65be 985 int ret = 0;
dac5c838 986 struct bt_value *attr_value = NULL;
273b65be
JG
987
988 assert(event_class);
989 assert(context);
b8248cc0
PP
990
991 context->current_indentation_level = 1;
992 g_string_assign(context->field_name, "");
993 g_string_append(context->string, "event {\n");
994 count = bt_ctf_event_class_get_attribute_count(event_class);
995
996 if (count < 0) {
2f100782
JG
997 ret = -1;
998 goto end;
999 }
1000
b8248cc0
PP
1001 for (i = 0; i < count; ++i) {
1002 const char *attr_name = NULL;
1003
1004 attr_name = bt_ctf_event_class_get_attribute_name(
1005 event_class, i);
1006 attr_value = bt_ctf_event_class_get_attribute_value(
1007 event_class, i);
1008
1009 if (!attr_name || !attr_value) {
1010 ret = -1;
1011 goto end;
1012 }
1013
dac5c838
PP
1014 switch (bt_value_get_type(attr_value)) {
1015 case BT_VALUE_TYPE_INTEGER:
b8248cc0
PP
1016 {
1017 int64_t value;
1018
dac5c838 1019 ret = bt_value_integer_get(attr_value, &value);
b8248cc0
PP
1020
1021 if (ret) {
1022 goto end;
1023 }
1024
1025 g_string_append_printf(context->string,
1026 "\t%s = %" PRId64 ";\n", attr_name, value);
1027 break;
1028 }
1029
dac5c838 1030 case BT_VALUE_TYPE_STRING:
b8248cc0
PP
1031 {
1032 const char *value;
1033
dac5c838 1034 ret = bt_value_string_get(attr_value, &value);
b8248cc0
PP
1035
1036 if (ret) {
1037 goto end;
1038 }
1039
1040 g_string_append_printf(context->string,
1041 "\t%s = \"%s\";\n", attr_name, value);
1042 break;
1043 }
1044
1045 default:
1046 /* should never happen */
1047 assert(false);
1048 break;
1049 }
1050
83509119 1051 BT_PUT(attr_value);
b8248cc0 1052 }
273b65be
JG
1053
1054 if (event_class->context) {
1055 g_string_append(context->string, "\tcontext := ");
1056 ret = bt_ctf_field_type_serialize(event_class->context,
1057 context);
1058 if (ret) {
1059 goto end;
1060 }
1061 g_string_append(context->string, ";\n");
1062 }
1063
1064 if (event_class->fields) {
1065 g_string_append(context->string, "\tfields := ");
1066 ret = bt_ctf_field_type_serialize(event_class->fields, context);
1067 if (ret) {
1068 goto end;
1069 }
1070 g_string_append(context->string, ";\n");
1071 }
1072
1073 g_string_append(context->string, "};\n\n");
1074end:
1075 context->current_indentation_level = 0;
83509119 1076 BT_PUT(attr_value);
273b65be
JG
1077 return ret;
1078}
1079
c35a1669
JG
1080void bt_ctf_event_class_set_native_byte_order(
1081 struct bt_ctf_event_class *event_class,
1082 int byte_order)
1083{
1084 if (!event_class) {
1085 return;
1086 }
1087
1088 bt_ctf_field_type_set_native_byte_order(event_class->context,
1089 byte_order);
1090 bt_ctf_field_type_set_native_byte_order(event_class->fields,
1091 byte_order);
1092}
1093
273b65be
JG
1094BT_HIDDEN
1095int bt_ctf_event_validate(struct bt_ctf_event *event)
1096{
1097 /* Make sure each field's payload has been set */
1098 int ret;
1099
1100 assert(event);
662e778c
JG
1101 ret = bt_ctf_field_validate(event->event_header);
1102 if (ret) {
1103 goto end;
1104 }
1105
273b65be
JG
1106 ret = bt_ctf_field_validate(event->fields_payload);
1107 if (ret) {
1108 goto end;
1109 }
1110
1111 if (event->event_class->context) {
1112 ret = bt_ctf_field_validate(event->context_payload);
1113 }
1114end:
1115 return ret;
1116}
1117
1118BT_HIDDEN
1119int bt_ctf_event_serialize(struct bt_ctf_event *event,
1120 struct ctf_stream_pos *pos)
1121{
1122 int ret = 0;
1123
1124 assert(event);
1125 assert(pos);
1126 if (event->context_payload) {
1127 ret = bt_ctf_field_serialize(event->context_payload, pos);
1128 if (ret) {
1129 goto end;
1130 }
1131 }
1132
1133 if (event->fields_payload) {
1134 ret = bt_ctf_field_serialize(event->fields_payload, pos);
1135 if (ret) {
1136 goto end;
1137 }
1138 }
1139end:
1140 return ret;
1141}
1142
662e778c
JG
1143BT_HIDDEN
1144int bt_ctf_event_populate_event_header(struct bt_ctf_event *event)
1145{
1146 int ret = 0;
1147 struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL;
1148
1149 if (!event) {
1150 ret = -1;
1151 goto end;
1152 }
1153
1154 id_field = bt_ctf_field_structure_get_field(event->event_header, "id");
1155 if (id_field) {
1156 ret = set_integer_field_value(id_field,
b8248cc0
PP
1157 (uint64_t) bt_ctf_event_class_get_id(
1158 event->event_class));
662e778c
JG
1159 if (ret) {
1160 goto end;
1161 }
1162 }
1163
1164 timestamp_field = bt_ctf_field_structure_get_field(event->event_header,
1165 "timestamp");
1166 if (timestamp_field) {
9a220c32
JG
1167 struct bt_ctf_field_type *timestamp_field_type =
1168 bt_ctf_field_get_type(timestamp_field);
1169 struct bt_ctf_clock *mapped_clock;
1170
1171 assert(timestamp_field_type);
1172 mapped_clock = bt_ctf_field_type_integer_get_mapped_clock(
1173 timestamp_field_type);
83509119 1174 bt_put(timestamp_field_type);
9a220c32
JG
1175 if (mapped_clock) {
1176 uint64_t timestamp = bt_ctf_clock_get_time(
1177 mapped_clock);
1178
83509119 1179 bt_put(mapped_clock);
9a220c32
JG
1180 if (timestamp == (uint64_t) -1ULL) {
1181 goto end;
1182 }
1183
1184 ret = set_integer_field_value(timestamp_field,
1185 timestamp);
1186 if (ret) {
1187 goto end;
1188 }
662e778c
JG
1189 }
1190 }
1191end:
83509119
JG
1192 bt_put(id_field);
1193 bt_put(timestamp_field);
662e778c
JG
1194 return ret;
1195}
123fbdec
JG
1196
1197BT_HIDDEN
1198int bt_ctf_event_set_stream(struct bt_ctf_event *event,
1199 struct bt_ctf_stream *stream)
1200{
1201 int ret = 0;
1202
1203 if (!event) {
1204 ret = -1;
1205 goto end;
1206 }
1207
1208 if (event->stream && stream) {
1209 /* Already attached to a stream */
1210 ret = -1;
1211 goto end;
1212 }
1213
1214 event->stream = stream;
1215end:
1216 return ret;
1217}
9c4c8f6e
PP
1218
1219struct bt_ctf_event *bt_ctf_event_copy(struct bt_ctf_event *event)
1220{
1221 struct bt_ctf_event *copy = NULL;
1222
1223 if (!event) {
1224 goto error;
1225 }
1226
1227 copy = g_new0(struct bt_ctf_event, 1);
1228 if (!copy) {
1229 goto error;
1230 }
1231
83509119 1232 bt_object_init(copy, bt_ctf_event_destroy);
9c4c8f6e 1233 copy->event_class = event->event_class;
83509119 1234 bt_get(copy->event_class);
9c4c8f6e
PP
1235 copy->stream = event->stream;
1236
1237 if (event->event_header) {
1238 copy->event_header = bt_ctf_field_copy(event->event_header);
1239
1240 if (!copy->event_header) {
1241 goto error;
1242 }
1243 }
1244
1245 if (event->context_payload) {
1246 copy->context_payload = bt_ctf_field_copy(
1247 event->context_payload);
1248
1249 if (!copy->context_payload) {
1250 goto error;
1251 }
1252 }
1253
1254 if (event->fields_payload) {
1255 copy->fields_payload = bt_ctf_field_copy(event->fields_payload);
1256
1257 if (!copy->fields_payload) {
1258 goto error;
1259 }
1260 }
1261
1262 return copy;
1263
1264error:
83509119
JG
1265 BT_PUT(copy);
1266 return copy;
9c4c8f6e 1267}
This page took 0.082377 seconds and 4 git commands to generate.