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