Update include/babeltrace/babeltrace.h
[babeltrace.git] / lib / ctf-ir / event-class.c
CommitLineData
272df73e
PP
1/*
2 * event-class.c
3 *
4 * Babeltrace CTF IR - Event class
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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-ir/fields-internal.h>
30#include <babeltrace/ctf-ir/field-types-internal.h>
31#include <babeltrace/ctf-ir/event-class.h>
32#include <babeltrace/ctf-ir/event-class-internal.h>
33#include <babeltrace/ctf-ir/stream-class.h>
34#include <babeltrace/ctf-ir/stream-class-internal.h>
35#include <babeltrace/ctf-ir/trace-internal.h>
36#include <babeltrace/ctf-ir/validation-internal.h>
37#include <babeltrace/ctf-ir/utils.h>
38#include <babeltrace/ref.h>
39#include <babeltrace/ctf-ir/attributes-internal.h>
3d9990ac
PP
40#include <babeltrace/compiler-internal.h>
41#include <babeltrace/endian-internal.h>
dc3fffef 42#include <inttypes.h>
272df73e
PP
43
44static
45void bt_ctf_event_class_destroy(struct bt_object *obj);
46
47struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
48{
49 int ret;
50 struct bt_value *obj = NULL;
51 struct bt_ctf_event_class *event_class = NULL;
52
53 if (bt_ctf_validate_identifier(name)) {
54 goto error;
55 }
56
57 event_class = g_new0(struct bt_ctf_event_class, 1);
58 if (!event_class) {
59 goto error;
60 }
61
5990dd44 62 event_class->id = -1;
272df73e
PP
63 bt_object_init(event_class, bt_ctf_event_class_destroy);
64 event_class->fields = bt_ctf_field_type_structure_create();
65 if (!event_class->fields) {
66 goto error;
67 }
68
53a1cae7
PP
69 event_class->context = bt_ctf_field_type_structure_create();
70 if (!event_class->context) {
71 goto error;
72 }
73
272df73e
PP
74 event_class->attributes = bt_ctf_attributes_create();
75 if (!event_class->attributes) {
76 goto error;
77 }
78
79 obj = bt_value_integer_create_init(-1);
80 if (!obj) {
81 goto error;
82 }
83
84 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
85 "id", obj);
86 if (ret) {
87 goto error;
88 }
89
90 BT_PUT(obj);
91
92 obj = bt_value_string_create_init(name);
93 if (!obj) {
94 goto error;
95 }
96
97 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
98 "name", obj);
99 if (ret) {
100 goto error;
101 }
102
103 BT_PUT(obj);
104
105 return event_class;
106
107error:
108 BT_PUT(event_class);
109 BT_PUT(obj);
110 return event_class;
111}
112
113const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
114{
115 struct bt_value *obj = NULL;
116 const char *name = NULL;
117
118 if (!event_class) {
119 goto end;
120 }
121
5990dd44
JG
122 if (event_class->name) {
123 name = event_class->name;
124 goto end;
125 }
126
272df73e
PP
127 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
128 BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
129 if (!obj) {
130 goto end;
131 }
132
133 if (bt_value_string_get(obj, &name)) {
134 name = NULL;
135 }
136
137end:
138 BT_PUT(obj);
139 return name;
140}
141
142int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
143{
144 struct bt_value *obj = NULL;
145 int64_t ret = 0;
146
147 if (!event_class) {
9ac68eb1 148 ret = (int64_t) -1;
272df73e
PP
149 goto end;
150 }
151
5990dd44 152 if (event_class->id >= 0) {
9ac68eb1 153 ret = (int64_t) event_class->id;
5990dd44
JG
154 goto end;
155 }
156
272df73e
PP
157 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
158 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
159 if (!obj) {
160 goto end;
161 }
162
163 if (bt_value_integer_get(obj, &ret)) {
9ac68eb1 164 ret = (int64_t) -1;
272df73e
PP
165 }
166
167 if (ret < 0) {
168 /* means ID is not set */
9ac68eb1 169 ret = (int64_t) -1;
272df73e
PP
170 goto end;
171 }
172
173end:
174 BT_PUT(obj);
175 return ret;
176}
177
178int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
9ac68eb1 179 uint64_t id_param)
272df73e
PP
180{
181 int ret = 0;
182 struct bt_value *obj = NULL;
183 struct bt_ctf_stream_class *stream_class = NULL;
9ac68eb1 184 int64_t id = (int64_t) id_param;
272df73e 185
9ac68eb1 186 if (!event_class || id < 0) {
272df73e
PP
187 ret = -1;
188 goto end;
189 }
190
191 stream_class = bt_ctf_event_class_get_stream_class(event_class);
192 if (stream_class) {
193 /*
194 * We don't allow changing the id if the event class has already
195 * been added to a stream class.
196 */
197 ret = -1;
198 goto end;
199 }
200
201 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
202 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
203 if (!obj) {
204 goto end;
205 }
206
207 if (bt_value_integer_set(obj, id)) {
208 ret = -1;
209 goto end;
210 }
211
212end:
213 BT_PUT(obj);
214 BT_PUT(stream_class);
215 return ret;
216}
217
218int bt_ctf_event_class_set_attribute(
219 struct bt_ctf_event_class *event_class, const char *name,
220 struct bt_value *value)
221{
222 int ret = 0;
223
224 if (!event_class || !name || !value || event_class->frozen) {
225 ret = -1;
226 goto end;
227 }
228
2073703a
JG
229 if (!strcmp(name, "id") || !strcmp(name, "loglevel") ||
230 !strcmp(name, "stream_id")) {
272df73e
PP
231 if (!bt_value_is_integer(value)) {
232 ret = -1;
233 goto end;
234 }
c3c30b08
MD
235 } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") ||
236 !strcmp(name, "loglevel_string")) {
272df73e
PP
237 if (!bt_value_is_string(value)) {
238 ret = -1;
239 goto end;
240 }
241 } else {
242 /* unknown attribute */
243 ret = -1;
244 goto end;
245 }
246
247 /* "id" special case: >= 0 */
248 if (!strcmp(name, "id")) {
249 int64_t val;
250
251 ret = bt_value_integer_get(value, &val);
252
253 if (ret) {
254 goto end;
255 }
256
257 if (val < 0) {
258 ret = -1;
259 goto end;
260 }
261 }
262
263 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
2073703a 264 name, value);
272df73e
PP
265
266end:
267 return ret;
268}
269
544d0515 270int64_t bt_ctf_event_class_get_attribute_count(
272df73e
PP
271 struct bt_ctf_event_class *event_class)
272{
9ac68eb1 273 int64_t ret;
272df73e
PP
274
275 if (!event_class) {
9ac68eb1 276 ret = (int64_t) -1;
272df73e
PP
277 goto end;
278 }
279
280 ret = bt_ctf_attributes_get_count(event_class->attributes);
281
282end:
283 return ret;
284}
285
286const char *
9ac68eb1
PP
287bt_ctf_event_class_get_attribute_name_by_index(
288 struct bt_ctf_event_class *event_class, uint64_t index)
272df73e
PP
289{
290 const char *ret;
291
292 if (!event_class) {
293 ret = NULL;
294 goto end;
295 }
296
297 ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
298
299end:
300 return ret;
301}
302
303struct bt_value *
9ac68eb1
PP
304bt_ctf_event_class_get_attribute_value_by_index(
305 struct bt_ctf_event_class *event_class, uint64_t index)
272df73e
PP
306{
307 struct bt_value *ret;
308
309 if (!event_class) {
310 ret = NULL;
311 goto end;
312 }
313
314 ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
315
316end:
317 return ret;
318}
319
320struct bt_value *
321bt_ctf_event_class_get_attribute_value_by_name(
322 struct bt_ctf_event_class *event_class, const char *name)
323{
324 struct bt_value *ret;
325
326 if (!event_class || !name) {
327 ret = NULL;
328 goto end;
329 }
330
331 ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
332 name);
333
334end:
335 return ret;
336
337}
338
339struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
340 struct bt_ctf_event_class *event_class)
341{
dc3fffef
PP
342 return event_class ?
343 bt_get(bt_ctf_event_class_borrow_stream_class(event_class)) :
344 NULL;
272df73e
PP
345}
346
347struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
348 struct bt_ctf_event_class *event_class)
349{
350 struct bt_ctf_field_type *payload = NULL;
351
352 if (!event_class) {
353 goto end;
354 }
355
356 bt_get(event_class->fields);
357 payload = event_class->fields;
358end:
359 return payload;
360}
361
362int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
363 struct bt_ctf_field_type *payload)
364{
365 int ret = 0;
366
835b2d10
JG
367 if (!event_class) {
368 ret = -1;
369 goto end;
370 }
371
372 if (payload && bt_ctf_field_type_get_type_id(payload) !=
1487a16a 373 BT_CTF_FIELD_TYPE_ID_STRUCT) {
272df73e
PP
374 ret = -1;
375 goto end;
376 }
377
272df73e 378 bt_put(event_class->fields);
835b2d10 379 event_class->fields = bt_get(payload);
272df73e
PP
380end:
381 return ret;
382}
383
384int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
385 struct bt_ctf_field_type *type,
386 const char *name)
387{
388 int ret = 0;
389
390 if (!event_class || !type || bt_ctf_validate_identifier(name) ||
391 event_class->frozen) {
392 ret = -1;
393 goto end;
394 }
395
396 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
1487a16a 397 BT_CTF_FIELD_TYPE_ID_STRUCT) {
272df73e
PP
398 ret = -1;
399 goto end;
400 }
401
402 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
403 type, name);
404end:
405 return ret;
406}
407
9ac68eb1 408int64_t bt_ctf_event_class_get_payload_type_field_count(
272df73e
PP
409 struct bt_ctf_event_class *event_class)
410{
544d0515 411 int64_t ret;
272df73e
PP
412
413 if (!event_class) {
9ac68eb1 414 ret = (int64_t) -1;
272df73e
PP
415 goto end;
416 }
417
418 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
1487a16a 419 BT_CTF_FIELD_TYPE_ID_STRUCT) {
9ac68eb1 420 ret = (int64_t) -1;
272df73e
PP
421 goto end;
422 }
423
424 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
425end:
426 return ret;
427}
428
9ac68eb1
PP
429int bt_ctf_event_class_get_payload_type_field_by_index(
430 struct bt_ctf_event_class *event_class,
272df73e 431 const char **field_name, struct bt_ctf_field_type **field_type,
9ac68eb1 432 uint64_t index)
272df73e
PP
433{
434 int ret;
435
9ac68eb1 436 if (!event_class) {
272df73e
PP
437 ret = -1;
438 goto end;
439 }
440
441 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
1487a16a 442 BT_CTF_FIELD_TYPE_ID_STRUCT) {
272df73e
PP
443 ret = -1;
444 goto end;
445 }
446
447 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
448 field_name, field_type, index);
449end:
450 return ret;
451}
452
9ac68eb1
PP
453struct bt_ctf_field_type *
454bt_ctf_event_class_get_payload_type_field_type_by_name(
272df73e
PP
455 struct bt_ctf_event_class *event_class, const char *name)
456{
457 GQuark name_quark;
458 struct bt_ctf_field_type *field_type = NULL;
459
460 if (!event_class || !name) {
461 goto end;
462 }
463
464 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
1487a16a 465 BT_CTF_FIELD_TYPE_ID_STRUCT) {
272df73e
PP
466 goto end;
467 }
468
469 name_quark = g_quark_try_string(name);
470 if (!name_quark) {
471 goto end;
472 }
473
474 /*
475 * No need to increment field_type's reference count since getting it
476 * from the structure already does.
477 */
478 field_type = bt_ctf_field_type_structure_get_field_type_by_name(
479 event_class->fields, name);
480end:
481 return field_type;
482}
483
484struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
485 struct bt_ctf_event_class *event_class)
486{
487 struct bt_ctf_field_type *context_type = NULL;
488
489 if (!event_class || !event_class->context) {
490 goto end;
491 }
492
493 bt_get(event_class->context);
494 context_type = event_class->context;
495end:
496 return context_type;
497}
498
499int bt_ctf_event_class_set_context_type(
500 struct bt_ctf_event_class *event_class,
501 struct bt_ctf_field_type *context)
502{
503 int ret = 0;
504
835b2d10 505 if (!event_class || event_class->frozen) {
272df73e
PP
506 ret = -1;
507 goto end;
508 }
509
835b2d10 510 if (context && bt_ctf_field_type_get_type_id(context) !=
1487a16a 511 BT_CTF_FIELD_TYPE_ID_STRUCT) {
272df73e
PP
512 ret = -1;
513 goto end;
514 }
515
272df73e 516 bt_put(event_class->context);
835b2d10 517 event_class->context = bt_get(context);
272df73e
PP
518end:
519 return ret;
520
521}
522
523void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
524{
525 bt_get(event_class);
526}
527
528void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
529{
530 bt_put(event_class);
531}
532
533BT_HIDDEN
534int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
9ac68eb1 535 uint64_t stream_id_param)
272df73e
PP
536{
537 int ret = 0;
9ac68eb1
PP
538 struct bt_value *obj = NULL;
539 int64_t stream_id = (int64_t) stream_id_param;
540
541 assert(event_class);
542
543 if (stream_id < 0) {
544 ret = -1;
545 goto end;
546 }
272df73e
PP
547
548 obj = bt_value_integer_create_init(stream_id);
549
550 if (!obj) {
551 ret = -1;
552 goto end;
553 }
554
555 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
556 "stream_id", obj);
557
558 if (event_class->frozen) {
559 bt_ctf_attributes_freeze(event_class->attributes);
560 }
561
562end:
563 BT_PUT(obj);
564 return ret;
565}
566
567static
568void bt_ctf_event_class_destroy(struct bt_object *obj)
569{
570 struct bt_ctf_event_class *event_class;
571
572 event_class = container_of(obj, struct bt_ctf_event_class, base);
573 bt_ctf_attributes_destroy(event_class->attributes);
574 bt_put(event_class->context);
575 bt_put(event_class->fields);
576 g_free(event_class);
577}
578
579BT_HIDDEN
580void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
581{
582 assert(event_class);
583 event_class->frozen = 1;
5990dd44
JG
584 event_class->name = bt_ctf_event_class_get_name(event_class);
585 event_class->id = bt_ctf_event_class_get_id(event_class);
272df73e
PP
586 bt_ctf_field_type_freeze(event_class->context);
587 bt_ctf_field_type_freeze(event_class->fields);
588 bt_ctf_attributes_freeze(event_class->attributes);
589}
590
591BT_HIDDEN
592int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
593 struct metadata_context *context)
594{
544d0515
PP
595 int64_t i;
596 int64_t count;
272df73e
PP
597 int ret = 0;
598 struct bt_value *attr_value = NULL;
599
600 assert(event_class);
601 assert(context);
602
603 context->current_indentation_level = 1;
604 g_string_assign(context->field_name, "");
605 g_string_append(context->string, "event {\n");
606 count = bt_ctf_event_class_get_attribute_count(event_class);
607
608 if (count < 0) {
609 ret = -1;
610 goto end;
611 }
612
613 for (i = 0; i < count; ++i) {
614 const char *attr_name = NULL;
615
9ac68eb1 616 attr_name = bt_ctf_event_class_get_attribute_name_by_index(
272df73e 617 event_class, i);
9ac68eb1 618 attr_value = bt_ctf_event_class_get_attribute_value_by_index(
272df73e
PP
619 event_class, i);
620
621 if (!attr_name || !attr_value) {
622 ret = -1;
623 goto end;
624 }
625
626 switch (bt_value_get_type(attr_value)) {
627 case BT_VALUE_TYPE_INTEGER:
628 {
629 int64_t value;
630
631 ret = bt_value_integer_get(attr_value, &value);
632
633 if (ret) {
634 goto end;
635 }
636
637 g_string_append_printf(context->string,
638 "\t%s = %" PRId64 ";\n", attr_name, value);
639 break;
640 }
641
642 case BT_VALUE_TYPE_STRING:
643 {
644 const char *value;
645
646 ret = bt_value_string_get(attr_value, &value);
647
648 if (ret) {
649 goto end;
650 }
651
652 g_string_append_printf(context->string,
653 "\t%s = \"%s\";\n", attr_name, value);
654 break;
655 }
656
657 default:
658 /* should never happen */
659 assert(false);
660 break;
661 }
662
663 BT_PUT(attr_value);
664 }
665
666 if (event_class->context) {
667 g_string_append(context->string, "\tcontext := ");
668 ret = bt_ctf_field_type_serialize(event_class->context,
669 context);
670 if (ret) {
671 goto end;
672 }
673 g_string_append(context->string, ";\n");
674 }
675
676 if (event_class->fields) {
677 g_string_append(context->string, "\tfields := ");
678 ret = bt_ctf_field_type_serialize(event_class->fields, context);
679 if (ret) {
680 goto end;
681 }
682 g_string_append(context->string, ";\n");
683 }
684
685 g_string_append(context->string, "};\n\n");
686end:
687 context->current_indentation_level = 0;
688 BT_PUT(attr_value);
689 return ret;
690}
This page took 0.058052 seconds and 4 git commands to generate.