ir: do not create empty structure for optional scope field types
[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
f8b979f9
PP
29#define BT_LOG_TAG "EVENT-CLASS"
30#include <babeltrace/lib-logging-internal.h>
31
272df73e
PP
32#include <babeltrace/ctf-ir/fields-internal.h>
33#include <babeltrace/ctf-ir/field-types-internal.h>
34#include <babeltrace/ctf-ir/event-class.h>
35#include <babeltrace/ctf-ir/event-class-internal.h>
36#include <babeltrace/ctf-ir/stream-class.h>
37#include <babeltrace/ctf-ir/stream-class-internal.h>
38#include <babeltrace/ctf-ir/trace-internal.h>
39#include <babeltrace/ctf-ir/validation-internal.h>
40#include <babeltrace/ctf-ir/utils.h>
41#include <babeltrace/ref.h>
42#include <babeltrace/ctf-ir/attributes-internal.h>
3d9990ac
PP
43#include <babeltrace/compiler-internal.h>
44#include <babeltrace/endian-internal.h>
c55a9f58 45#include <babeltrace/types.h>
f8b979f9 46#include <babeltrace/values-internal.h>
dc3fffef 47#include <inttypes.h>
0fbb9a9f 48#include <stdlib.h>
272df73e
PP
49
50static
51void bt_ctf_event_class_destroy(struct bt_object *obj);
52
53struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
54{
55 int ret;
56 struct bt_value *obj = NULL;
57 struct bt_ctf_event_class *event_class = NULL;
58
f8b979f9
PP
59 BT_LOGD("Creating event class object: name=\"%s\"",
60 name);
61
272df73e 62 if (bt_ctf_validate_identifier(name)) {
f8b979f9
PP
63 BT_LOGW("Invalid parameter: event class's name is not a valid CTF identifier: "
64 "name=\"%s\"", name);
272df73e
PP
65 goto error;
66 }
67
68 event_class = g_new0(struct bt_ctf_event_class, 1);
69 if (!event_class) {
f8b979f9 70 BT_LOGE_STR("Failed to allocate one event class.");
272df73e
PP
71 goto error;
72 }
73
5990dd44 74 event_class->id = -1;
272df73e
PP
75 bt_object_init(event_class, bt_ctf_event_class_destroy);
76 event_class->fields = bt_ctf_field_type_structure_create();
77 if (!event_class->fields) {
f8b979f9 78 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
272df73e
PP
79 goto error;
80 }
81
82 event_class->attributes = bt_ctf_attributes_create();
83 if (!event_class->attributes) {
f8b979f9 84 BT_LOGE_STR("Cannot create event class's attributes object.");
272df73e
PP
85 goto error;
86 }
87
88 obj = bt_value_integer_create_init(-1);
89 if (!obj) {
f8b979f9 90 BT_LOGE_STR("Cannot create integer value object.");
272df73e
PP
91 goto error;
92 }
93
94 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
95 "id", obj);
96 if (ret) {
f8b979f9
PP
97 BT_LOGE("Cannot set event class's attributes's `id` field: ret=%d",
98 ret);
272df73e
PP
99 goto error;
100 }
101
102 BT_PUT(obj);
103
104 obj = bt_value_string_create_init(name);
105 if (!obj) {
f8b979f9 106 BT_LOGE_STR("Cannot create string value object.");
272df73e
PP
107 goto error;
108 }
109
110 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
111 "name", obj);
112 if (ret) {
f8b979f9
PP
113 BT_LOGE("Cannot set event class's attributes's `name` field: ret=%d",
114 ret);
272df73e
PP
115 goto error;
116 }
117
118 BT_PUT(obj);
f8b979f9
PP
119 BT_LOGD("Created event class object: addr=%p, name=\"%s\"",
120 event_class, bt_ctf_event_class_get_name(event_class));
272df73e
PP
121 return event_class;
122
123error:
124 BT_PUT(event_class);
125 BT_PUT(obj);
126 return event_class;
127}
128
129const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
130{
131 struct bt_value *obj = NULL;
132 const char *name = NULL;
f8b979f9 133 int ret;
272df73e
PP
134
135 if (!event_class) {
f8b979f9 136 BT_LOGW_STR("Invalid parameter: event class is NULL.");
272df73e
PP
137 goto end;
138 }
139
5990dd44
JG
140 if (event_class->name) {
141 name = event_class->name;
142 goto end;
143 }
144
272df73e
PP
145 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
146 BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
f8b979f9
PP
147 assert(obj);
148 ret = bt_value_string_get(obj, &name);
149 assert(ret == 0);
272df73e
PP
150
151end:
152 BT_PUT(obj);
153 return name;
154}
155
156int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
157{
158 struct bt_value *obj = NULL;
159 int64_t ret = 0;
f8b979f9 160 int int_ret;
272df73e
PP
161
162 if (!event_class) {
f8b979f9 163 BT_LOGW_STR("Invalid parameter: event class is NULL.");
9ac68eb1 164 ret = (int64_t) -1;
272df73e
PP
165 goto end;
166 }
167
5990dd44 168 if (event_class->id >= 0) {
9ac68eb1 169 ret = (int64_t) event_class->id;
5990dd44
JG
170 goto end;
171 }
172
272df73e
PP
173 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
174 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
f8b979f9
PP
175 assert(obj);
176 int_ret = bt_value_integer_get(obj, &ret);
177 assert(int_ret == 0);
272df73e
PP
178 if (ret < 0) {
179 /* means ID is not set */
f8b979f9
PP
180 BT_LOGV("Event class's ID is not set: addr=%p, name=\"%s\"",
181 event_class, bt_ctf_event_class_get_name(event_class));
9ac68eb1 182 ret = (int64_t) -1;
272df73e
PP
183 goto end;
184 }
185
186end:
187 BT_PUT(obj);
188 return ret;
189}
190
191int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
9ac68eb1 192 uint64_t id_param)
272df73e
PP
193{
194 int ret = 0;
195 struct bt_value *obj = NULL;
9ac68eb1 196 int64_t id = (int64_t) id_param;
272df73e 197
f8b979f9
PP
198 if (!event_class) {
199 BT_LOGW_STR("Invalid parameter: event class is NULL.");
272df73e
PP
200 ret = -1;
201 goto end;
202 }
203
f8b979f9
PP
204 if (event_class->frozen) {
205 BT_LOGW("Invalid parameter: event class is frozen: "
206 "addr=%p, name=\"%s\", id=%" PRId64,
207 event_class, bt_ctf_event_class_get_name(event_class),
208 bt_ctf_event_class_get_id(event_class));
272df73e
PP
209 ret = -1;
210 goto end;
211 }
212
f8b979f9
PP
213 if (id < 0) {
214 BT_LOGW("Invalid parameter: invalid event class's ID: "
215 "addr=%p, name=\"%s\", id=%" PRIu64,
216 event_class, bt_ctf_event_class_get_name(event_class),
217 id_param);
272df73e
PP
218 ret = -1;
219 goto end;
220 }
221
f8b979f9
PP
222 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
223 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
224 assert(obj);
225 ret = bt_value_integer_set(obj, id);
226 assert(ret == 0);
227 BT_LOGV("Set event class's ID: "
228 "addr=%p, name=\"%s\", id=%" PRId64,
229 event_class, bt_ctf_event_class_get_name(event_class), id);
230
272df73e
PP
231end:
232 BT_PUT(obj);
272df73e
PP
233 return ret;
234}
235
236int bt_ctf_event_class_set_attribute(
237 struct bt_ctf_event_class *event_class, const char *name,
238 struct bt_value *value)
239{
240 int ret = 0;
241
f8b979f9
PP
242 if (!event_class || !name || !value) {
243 BT_LOGW("Invalid parameter: event class, name, or value is NULL: "
244 "event-class-addr=%p, name-addr=%p, value-addr=%p",
245 event_class, name, value);
246 ret = -1;
247 goto end;
248 }
249
250 if (event_class->frozen) {
251 BT_LOGW("Invalid parameter: event class is frozen: "
252 "addr=%p, name=\"%s\", id=%" PRId64 ", attr-name=\"%s\"",
253 event_class, bt_ctf_event_class_get_name(event_class),
254 bt_ctf_event_class_get_id(event_class), name);
272df73e
PP
255 ret = -1;
256 goto end;
257 }
258
2073703a
JG
259 if (!strcmp(name, "id") || !strcmp(name, "loglevel") ||
260 !strcmp(name, "stream_id")) {
272df73e 261 if (!bt_value_is_integer(value)) {
f8b979f9
PP
262 BT_LOGW("Invalid parameter: this event class's attribute must have an integer value: "
263 "event-class-addr=%p, event-class-name=\"%s\", "
264 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
265 "attr-type=%s", event_class,
266 bt_ctf_event_class_get_name(event_class),
267 bt_ctf_event_class_get_id(event_class), name,
268 bt_value_type_string(bt_value_get_type(value)));
272df73e
PP
269 ret = -1;
270 goto end;
271 }
c3c30b08
MD
272 } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") ||
273 !strcmp(name, "loglevel_string")) {
272df73e 274 if (!bt_value_is_string(value)) {
f8b979f9
PP
275 BT_LOGW("Invalid parameter: this event class's attribute must have a string value: "
276 "event-class-addr=%p, event-class-name=\"%s\", "
277 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
278 "attr-type=%s", event_class,
279 bt_ctf_event_class_get_name(event_class),
280 bt_ctf_event_class_get_id(event_class), name,
281 bt_value_type_string(bt_value_get_type(value)));
272df73e
PP
282 ret = -1;
283 goto end;
284 }
285 } else {
286 /* unknown attribute */
f8b979f9
PP
287 BT_LOGW("Invalid parameter: unknown event class's attribute name: "
288 "event-class-addr=%p, event-class-name=\"%s\", "
289 "event-class-id=%" PRId64 ", attr-name=\"%s\"",
290 event_class, bt_ctf_event_class_get_name(event_class),
291 bt_ctf_event_class_get_id(event_class), name);
272df73e
PP
292 ret = -1;
293 goto end;
294 }
295
296 /* "id" special case: >= 0 */
297 if (!strcmp(name, "id")) {
298 int64_t val;
299
300 ret = bt_value_integer_get(value, &val);
f8b979f9 301 assert(ret == 0);
0352f8fa 302 BT_LOGV("Setting event's ID: id=%" PRId64, val);
f8b979f9 303 ret = bt_ctf_event_class_set_id(event_class, (uint64_t) val);
272df73e
PP
304 if (ret) {
305 goto end;
306 }
272df73e
PP
307 }
308
309 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
2073703a 310 name, value);
f8b979f9
PP
311 assert(ret == 0);
312
313 if (BT_LOG_ON_VERBOSE) {
314 if (bt_value_is_integer(value)) {
315 int64_t val;
316
317 ret = bt_value_integer_get(value, &val);
318 assert(ret == 0);
319 BT_LOGV("Set event class's integer attribute: "
320 "event-class-addr=%p, event-class-name=\"%s\", "
321 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
322 "attr-value=%" PRId64,
323 event_class, bt_ctf_event_class_get_name(event_class),
324 bt_ctf_event_class_get_id(event_class), name,
325 val);
326 } else if (bt_value_is_string(value)) {
327 const char *val;
328
329 ret = bt_value_string_get(value, &val);
330 assert(ret == 0);
331 BT_LOGV("Set event class's string attribute: "
332 "event-class-addr=%p, event-class-name=\"%s\", "
333 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
334 "attr-value=\"%s\"",
335 event_class, bt_ctf_event_class_get_name(event_class),
336 bt_ctf_event_class_get_id(event_class), name,
337 val);
338 }
339 }
272df73e
PP
340
341end:
342 return ret;
343}
344
544d0515 345int64_t bt_ctf_event_class_get_attribute_count(
272df73e
PP
346 struct bt_ctf_event_class *event_class)
347{
9ac68eb1 348 int64_t ret;
272df73e
PP
349
350 if (!event_class) {
f8b979f9 351 BT_LOGW_STR("Invalid parameter: event class is NULL.");
9ac68eb1 352 ret = (int64_t) -1;
272df73e
PP
353 goto end;
354 }
355
356 ret = bt_ctf_attributes_get_count(event_class->attributes);
f8b979f9 357 assert(ret >= 0);
272df73e
PP
358
359end:
360 return ret;
361}
362
363const char *
9ac68eb1
PP
364bt_ctf_event_class_get_attribute_name_by_index(
365 struct bt_ctf_event_class *event_class, uint64_t index)
272df73e
PP
366{
367 const char *ret;
368
369 if (!event_class) {
f8b979f9 370 BT_LOGW_STR("Invalid parameter: event class is NULL.");
272df73e
PP
371 ret = NULL;
372 goto end;
373 }
374
375 ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
96373046 376 if (!ret) {
f8b979f9
PP
377 BT_LOGW("Cannot get event class's attribute name by index: "
378 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
379 event_class, bt_ctf_event_class_get_name(event_class),
380 bt_ctf_event_class_get_id(event_class), index);
381 }
272df73e
PP
382
383end:
384 return ret;
385}
386
387struct bt_value *
9ac68eb1
PP
388bt_ctf_event_class_get_attribute_value_by_index(
389 struct bt_ctf_event_class *event_class, uint64_t index)
272df73e
PP
390{
391 struct bt_value *ret;
392
393 if (!event_class) {
f8b979f9 394 BT_LOGW_STR("Invalid parameter: event class is NULL.");
272df73e
PP
395 ret = NULL;
396 goto end;
397 }
398
399 ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
96373046 400 if (!ret) {
f8b979f9
PP
401 BT_LOGW("Cannot get event class's attribute value by index: "
402 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
403 event_class, bt_ctf_event_class_get_name(event_class),
404 bt_ctf_event_class_get_id(event_class), index);
405 }
272df73e
PP
406
407end:
408 return ret;
409}
410
411struct bt_value *
412bt_ctf_event_class_get_attribute_value_by_name(
413 struct bt_ctf_event_class *event_class, const char *name)
414{
415 struct bt_value *ret;
416
417 if (!event_class || !name) {
32e87ceb 418 BT_LOGW("Invalid parameter: event class or name is NULL: "
f8b979f9
PP
419 "event-class-addr=%p, name-addr=%p",
420 event_class, name);
272df73e
PP
421 ret = NULL;
422 goto end;
423 }
424
425 ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
426 name);
96373046 427 if (!ret) {
f8b979f9
PP
428 BT_LOGV("Cannot find event class's attribute: "
429 "addr=%p, event-class-name=\"%s\", id=%" PRId64 ", "
430 "attr-name=\"%s\"",
431 event_class, bt_ctf_event_class_get_name(event_class),
432 bt_ctf_event_class_get_id(event_class), name);
433 }
272df73e
PP
434
435end:
436 return ret;
437
438}
439
440struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
441 struct bt_ctf_event_class *event_class)
442{
dc3fffef
PP
443 return event_class ?
444 bt_get(bt_ctf_event_class_borrow_stream_class(event_class)) :
445 NULL;
272df73e
PP
446}
447
448struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
449 struct bt_ctf_event_class *event_class)
450{
451 struct bt_ctf_field_type *payload = NULL;
452
453 if (!event_class) {
f8b979f9 454 BT_LOGW_STR("Invalid parameter: event class is NULL.");
272df73e
PP
455 goto end;
456 }
457
458 bt_get(event_class->fields);
459 payload = event_class->fields;
460end:
461 return payload;
462}
463
464int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
465 struct bt_ctf_field_type *payload)
466{
467 int ret = 0;
468
835b2d10 469 if (!event_class) {
f8b979f9 470 BT_LOGW_STR("Invalid parameter: event class is NULL.");
835b2d10
JG
471 ret = -1;
472 goto end;
473 }
474
475 if (payload && bt_ctf_field_type_get_type_id(payload) !=
1487a16a 476 BT_CTF_FIELD_TYPE_ID_STRUCT) {
f8b979f9
PP
477 BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
478 "addr=%p, name=\"%s\", id=%" PRId64 ", "
479 "payload-ft-addr=%p, payload-ft-id=%s",
480 event_class, bt_ctf_event_class_get_name(event_class),
481 bt_ctf_event_class_get_id(event_class), payload,
482 bt_ctf_field_type_id_string(
483 bt_ctf_field_type_get_type_id(payload)));
272df73e
PP
484 ret = -1;
485 goto end;
486 }
487
272df73e 488 bt_put(event_class->fields);
835b2d10 489 event_class->fields = bt_get(payload);
f8b979f9
PP
490 BT_LOGV("Set event class's payload field type: "
491 "event-class-addr=%p, event-class-name=\"%s\", "
492 "event-class-id=%" PRId64 ", payload-ft-addr=%p",
493 event_class, bt_ctf_event_class_get_name(event_class),
494 bt_ctf_event_class_get_id(event_class), payload);
272df73e
PP
495end:
496 return ret;
497}
498
499int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
500 struct bt_ctf_field_type *type,
501 const char *name)
502{
503 int ret = 0;
504
f8b979f9
PP
505 if (!event_class || !type) {
506 BT_LOGW("Invalid parameter: event class or field type is NULL: "
507 "event-class-addr=%p, field-type-addr=%p",
508 event_class, type);
509 ret = -1;
510 goto end;
511 }
512
513 if (bt_ctf_validate_identifier(name)) {
514 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
515 "addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"",
516 event_class, bt_ctf_event_class_get_name(event_class),
517 bt_ctf_event_class_get_id(event_class),
518 name);
272df73e
PP
519 ret = -1;
520 goto end;
521 }
522
f8b979f9
PP
523 if (event_class->frozen) {
524 BT_LOGW("Invalid parameter: event class is frozen: "
525 "addr=%p, name=\"%s\", id=%" PRId64,
526 event_class, bt_ctf_event_class_get_name(event_class),
527 bt_ctf_event_class_get_id(event_class));
272df73e
PP
528 ret = -1;
529 goto end;
530 }
531
f8b979f9
PP
532 if (!event_class->fields) {
533 BT_LOGW("Event class has no payload field type: "
534 "addr=%p, name=\"%s\", id=%" PRId64,
535 event_class, bt_ctf_event_class_get_name(event_class),
536 bt_ctf_event_class_get_id(event_class));
537 ret = -1;
538 goto end;
539 }
540
541 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
542 BT_CTF_FIELD_TYPE_ID_STRUCT);
272df73e
PP
543 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
544 type, name);
f8b979f9
PP
545 BT_LOGV("Added field to event class's payload field type: "
546 "event-class-addr=%p, event-class-name=\"%s\", "
547 "event-class-id=%" PRId64 ", field-name=\"%s\", ft-addr=%p",
548 event_class, bt_ctf_event_class_get_name(event_class),
549 bt_ctf_event_class_get_id(event_class), name, type);
272df73e
PP
550end:
551 return ret;
552}
553
9ac68eb1 554int64_t bt_ctf_event_class_get_payload_type_field_count(
272df73e
PP
555 struct bt_ctf_event_class *event_class)
556{
544d0515 557 int64_t ret;
272df73e
PP
558
559 if (!event_class) {
f8b979f9 560 BT_LOGW_STR("Invalid parameter: event class is NULL.");
9ac68eb1 561 ret = (int64_t) -1;
272df73e
PP
562 goto end;
563 }
564
f8b979f9
PP
565 if (!event_class->fields) {
566 BT_LOGV("Event class has no payload field type: "
567 "addr=%p, name=\"%s\", id=%" PRId64,
568 event_class, bt_ctf_event_class_get_name(event_class),
569 bt_ctf_event_class_get_id(event_class));
9ac68eb1 570 ret = (int64_t) -1;
272df73e
PP
571 goto end;
572 }
573
f8b979f9
PP
574 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
575 BT_CTF_FIELD_TYPE_ID_STRUCT);
272df73e
PP
576 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
577end:
578 return ret;
579}
580
9ac68eb1
PP
581int bt_ctf_event_class_get_payload_type_field_by_index(
582 struct bt_ctf_event_class *event_class,
272df73e 583 const char **field_name, struct bt_ctf_field_type **field_type,
9ac68eb1 584 uint64_t index)
272df73e
PP
585{
586 int ret;
587
9ac68eb1 588 if (!event_class) {
f8b979f9 589 BT_LOGW_STR("Invalid parameter: event class is NULL.");
272df73e
PP
590 ret = -1;
591 goto end;
592 }
593
f8b979f9
PP
594 if (!event_class->fields) {
595 BT_LOGV("Event class has no payload field type: "
596 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
597 event_class, bt_ctf_event_class_get_name(event_class),
598 bt_ctf_event_class_get_id(event_class), index);
272df73e
PP
599 ret = -1;
600 goto end;
601 }
602
f8b979f9
PP
603 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
604 BT_CTF_FIELD_TYPE_ID_STRUCT);
272df73e
PP
605 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
606 field_name, field_type, index);
607end:
608 return ret;
609}
610
9ac68eb1
PP
611struct bt_ctf_field_type *
612bt_ctf_event_class_get_payload_type_field_type_by_name(
272df73e
PP
613 struct bt_ctf_event_class *event_class, const char *name)
614{
615 GQuark name_quark;
616 struct bt_ctf_field_type *field_type = NULL;
617
618 if (!event_class || !name) {
32e87ceb 619 BT_LOGW("Invalid parameter: event class or name is NULL: "
f8b979f9
PP
620 "event-class-addr=%p, name-addr=%p",
621 event_class, name);
272df73e
PP
622 goto end;
623 }
624
f8b979f9
PP
625 if (!event_class->fields) {
626 BT_LOGV("Event class has no payload field type: "
627 "addr=%p, name=\"%s\", id=%" PRId64,
628 event_class, bt_ctf_event_class_get_name(event_class),
629 bt_ctf_event_class_get_id(event_class));
272df73e
PP
630 goto end;
631 }
632
f8b979f9
PP
633 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
634 BT_CTF_FIELD_TYPE_ID_STRUCT);
272df73e
PP
635 name_quark = g_quark_try_string(name);
636 if (!name_quark) {
f8b979f9 637 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
272df73e
PP
638 goto end;
639 }
640
641 /*
642 * No need to increment field_type's reference count since getting it
643 * from the structure already does.
644 */
645 field_type = bt_ctf_field_type_structure_get_field_type_by_name(
646 event_class->fields, name);
647end:
648 return field_type;
649}
650
651struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
652 struct bt_ctf_event_class *event_class)
653{
654 struct bt_ctf_field_type *context_type = NULL;
655
f8b979f9
PP
656 if (!event_class) {
657 BT_LOGW_STR("Invalid parameter: event class is NULL.");
658 goto end;
659 }
660
661 if (!event_class->context) {
662 BT_LOGV("Event class has no context field type: "
663 "addr=%p, name=\"%s\", id=%" PRId64,
664 event_class, bt_ctf_event_class_get_name(event_class),
665 bt_ctf_event_class_get_id(event_class));
272df73e
PP
666 goto end;
667 }
668
669 bt_get(event_class->context);
670 context_type = event_class->context;
671end:
672 return context_type;
673}
674
675int bt_ctf_event_class_set_context_type(
676 struct bt_ctf_event_class *event_class,
677 struct bt_ctf_field_type *context)
678{
679 int ret = 0;
680
f8b979f9
PP
681 if (!event_class) {
682 BT_LOGW_STR("Invalid parameter: event class is NULL.");
683 ret = -1;
684 goto end;
685 }
686
687 if (event_class->frozen) {
688 BT_LOGW("Invalid parameter: event class is frozen: "
689 "addr=%p, name=\"%s\", id=%" PRId64,
690 event_class, bt_ctf_event_class_get_name(event_class),
691 bt_ctf_event_class_get_id(event_class));
272df73e
PP
692 ret = -1;
693 goto end;
694 }
695
835b2d10 696 if (context && bt_ctf_field_type_get_type_id(context) !=
1487a16a 697 BT_CTF_FIELD_TYPE_ID_STRUCT) {
f8b979f9
PP
698 BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
699 "addr=%p, name=\"%s\", id=%" PRId64 ", "
700 "context-ft-id=%s",
701 event_class, bt_ctf_event_class_get_name(event_class),
702 bt_ctf_event_class_get_id(event_class),
703 bt_ctf_field_type_id_string(
704 bt_ctf_field_type_get_type_id(context)));
272df73e
PP
705 ret = -1;
706 goto end;
707 }
708
272df73e 709 bt_put(event_class->context);
835b2d10 710 event_class->context = bt_get(context);
f8b979f9
PP
711 BT_LOGV("Set event class's context field type: "
712 "event-class-addr=%p, event-class-name=\"%s\", "
713 "event-class-id=%" PRId64 ", context-ft-addr=%p",
714 event_class, bt_ctf_event_class_get_name(event_class),
715 bt_ctf_event_class_get_id(event_class), context);
272df73e
PP
716end:
717 return ret;
718
719}
720
f8b979f9 721/* Pre-2.0 CTF writer backward compatibility */
272df73e
PP
722void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
723{
724 bt_get(event_class);
725}
726
f8b979f9 727/* Pre-2.0 CTF writer backward compatibility */
272df73e
PP
728void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
729{
730 bt_put(event_class);
731}
732
733BT_HIDDEN
734int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
9ac68eb1 735 uint64_t stream_id_param)
272df73e
PP
736{
737 int ret = 0;
9ac68eb1
PP
738 struct bt_value *obj = NULL;
739 int64_t stream_id = (int64_t) stream_id_param;
740
741 assert(event_class);
f8b979f9 742 assert(stream_id >= 0);
272df73e 743 obj = bt_value_integer_create_init(stream_id);
272df73e 744 if (!obj) {
f8b979f9 745 BT_LOGE_STR("Cannot create integer value object.");
272df73e
PP
746 ret = -1;
747 goto end;
748 }
749
750 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
751 "stream_id", obj);
f8b979f9
PP
752 if (ret) {
753 BT_LOGE("Cannot set event class's attributes's `stream_id` field: "
754 "addr=%p, name=\"%s\", id=%" PRId64 ", ret=%d",
755 event_class, bt_ctf_event_class_get_name(event_class),
756 bt_ctf_event_class_get_id(event_class), ret);
757 goto end;
758 }
272df73e
PP
759
760 if (event_class->frozen) {
f8b979f9 761 BT_LOGV_STR("Freezing event class's attributes because event class is frozen.");
272df73e
PP
762 bt_ctf_attributes_freeze(event_class->attributes);
763 }
764
f8b979f9
PP
765 BT_LOGV("Set event class's stream class ID: "
766 "event-class-addr=%p, event-class-name=\"%s\", "
767 "event-class-id=%" PRId64 ", stream-class-id=%" PRId64,
768 event_class, bt_ctf_event_class_get_name(event_class),
769 bt_ctf_event_class_get_id(event_class), stream_id);
770
272df73e
PP
771end:
772 BT_PUT(obj);
773 return ret;
774}
775
776static
777void bt_ctf_event_class_destroy(struct bt_object *obj)
778{
779 struct bt_ctf_event_class *event_class;
780
781 event_class = container_of(obj, struct bt_ctf_event_class, base);
f8b979f9
PP
782 BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64,
783 event_class, bt_ctf_event_class_get_name(event_class),
784 bt_ctf_event_class_get_id(event_class));
0352f8fa 785 BT_LOGD_STR("Destroying event class's attributes.");
272df73e 786 bt_ctf_attributes_destroy(event_class->attributes);
03409974 787 BT_LOGD_STR("Putting context field type.");
272df73e 788 bt_put(event_class->context);
03409974 789 BT_LOGD_STR("Putting payload field type.");
272df73e
PP
790 bt_put(event_class->fields);
791 g_free(event_class);
792}
793
794BT_HIDDEN
795void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
796{
797 assert(event_class);
f8b979f9
PP
798
799 if (event_class->frozen) {
800 return;
801 }
802
803 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64,
804 event_class, bt_ctf_event_class_get_name(event_class),
805 bt_ctf_event_class_get_id(event_class));
272df73e 806 event_class->frozen = 1;
5990dd44
JG
807 event_class->name = bt_ctf_event_class_get_name(event_class);
808 event_class->id = bt_ctf_event_class_get_id(event_class);
0352f8fa 809 BT_LOGD_STR("Freezing event class's context field type.");
272df73e 810 bt_ctf_field_type_freeze(event_class->context);
0352f8fa 811 BT_LOGD_STR("Freezing event class's payload field type.");
272df73e 812 bt_ctf_field_type_freeze(event_class->fields);
0352f8fa 813 BT_LOGD_STR("Freezing event class's attributes.");
272df73e
PP
814 bt_ctf_attributes_freeze(event_class->attributes);
815}
816
817BT_HIDDEN
818int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
819 struct metadata_context *context)
820{
544d0515
PP
821 int64_t i;
822 int64_t count;
272df73e
PP
823 int ret = 0;
824 struct bt_value *attr_value = NULL;
825
826 assert(event_class);
827 assert(context);
f8b979f9
PP
828 BT_LOGD("Serializing event class's metadata: "
829 "event-class-addr=%p, event-class-name=\"%s\", "
830 "event-class-id=%" PRId64 ", metadata-context-addr=%p",
831 event_class, bt_ctf_event_class_get_name(event_class),
832 bt_ctf_event_class_get_id(event_class), context);
272df73e
PP
833 context->current_indentation_level = 1;
834 g_string_assign(context->field_name, "");
835 g_string_append(context->string, "event {\n");
836 count = bt_ctf_event_class_get_attribute_count(event_class);
f8b979f9 837 assert(count >= 0);
272df73e
PP
838
839 for (i = 0; i < count; ++i) {
840 const char *attr_name = NULL;
841
9ac68eb1 842 attr_name = bt_ctf_event_class_get_attribute_name_by_index(
272df73e 843 event_class, i);
f8b979f9 844 assert(attr_name);
9ac68eb1 845 attr_value = bt_ctf_event_class_get_attribute_value_by_index(
272df73e 846 event_class, i);
f8b979f9 847 assert(attr_value);
272df73e
PP
848
849 switch (bt_value_get_type(attr_value)) {
850 case BT_VALUE_TYPE_INTEGER:
851 {
852 int64_t value;
853
854 ret = bt_value_integer_get(attr_value, &value);
f8b979f9 855 assert(ret == 0);
272df73e
PP
856 g_string_append_printf(context->string,
857 "\t%s = %" PRId64 ";\n", attr_name, value);
858 break;
859 }
860
861 case BT_VALUE_TYPE_STRING:
862 {
863 const char *value;
864
865 ret = bt_value_string_get(attr_value, &value);
f8b979f9 866 assert(ret == 0);
272df73e
PP
867 g_string_append_printf(context->string,
868 "\t%s = \"%s\";\n", attr_name, value);
869 break;
870 }
871
872 default:
873 /* should never happen */
0fbb9a9f 874 abort();
272df73e
PP
875 break;
876 }
877
878 BT_PUT(attr_value);
879 }
880
881 if (event_class->context) {
882 g_string_append(context->string, "\tcontext := ");
0352f8fa 883 BT_LOGD_STR("Serializing event class's context field type metadata.");
272df73e
PP
884 ret = bt_ctf_field_type_serialize(event_class->context,
885 context);
886 if (ret) {
66871d36 887 BT_LOGW("Cannot serialize event class's context field type's metadata: "
f8b979f9 888 "ret=%d", ret);
272df73e
PP
889 goto end;
890 }
891 g_string_append(context->string, ";\n");
892 }
893
894 if (event_class->fields) {
895 g_string_append(context->string, "\tfields := ");
0352f8fa 896 BT_LOGD_STR("Serializing event class's payload field type metadata.");
272df73e
PP
897 ret = bt_ctf_field_type_serialize(event_class->fields, context);
898 if (ret) {
66871d36 899 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
f8b979f9 900 "ret=%d", ret);
272df73e
PP
901 goto end;
902 }
903 g_string_append(context->string, ";\n");
904 }
905
906 g_string_append(context->string, "};\n\n");
907end:
908 context->current_indentation_level = 0;
909 BT_PUT(attr_value);
910 return ret;
911}
This page took 0.073433 seconds and 4 git commands to generate.