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