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