Rename VERBOSE log level to TRACE
[babeltrace.git] / src / ctf-writer / event-class.c
CommitLineData
3dca2276
PP
1/*
2 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
350ad6c1 24#define BT_LOG_TAG "CTF-WRITER/EVENT-CLASS"
67d2ce02 25#include "logging.h"
3dca2276 26
578e048b
MJ
27#include <glib.h>
28#include <inttypes.h>
29#include <stdlib.h>
30
3fadfbc0 31#include <babeltrace2/ctf-writer/event.h>
3fadfbc0 32#include <babeltrace2/ctf-writer/field-types.h>
578e048b 33#include <babeltrace2/ctf-writer/object.h>
3fadfbc0 34#include <babeltrace2/ctf-writer/stream-class.h>
3fadfbc0 35#include <babeltrace2/ctf-writer/utils.h>
3fadfbc0 36#include <babeltrace2/types.h>
578e048b
MJ
37
38#include "common/assert.h"
39#include "compat/compiler.h"
40#include "compat/endian.h"
41
42#include "assert-pre.h"
43#include "attributes.h"
44#include "event-class.h"
45#include "event.h"
46#include "fields.h"
47#include "field-types.h"
48#include "stream-class.h"
49#include "trace.h"
50#include "utils.h"
51#include "validation.h"
52#include "values.h"
53#include "writer.h"
16ca5ff0
PP
54
55BT_HIDDEN
e1e02a22 56void bt_ctf_event_class_common_finalize(struct bt_ctf_object *obj)
16ca5ff0
PP
57{
58 struct bt_ctf_event_class_common *event_class;
59
60 event_class = container_of(obj, struct bt_ctf_event_class_common, base);
61 BT_LOGD("Finalizing common event class: addr=%p, name=\"%s\", id=%" PRId64,
62 event_class, bt_ctf_event_class_common_get_name(event_class),
63 bt_ctf_event_class_common_get_id(event_class));
64
65 if (event_class->name) {
66 g_string_free(event_class->name, TRUE);
67 }
68
69 if (event_class->emf_uri) {
70 g_string_free(event_class->emf_uri, TRUE);
71 }
72
73 BT_LOGD_STR("Putting context field type.");
e1e02a22 74 bt_ctf_object_put_ref(event_class->context_field_type);
16ca5ff0 75 BT_LOGD_STR("Putting payload field type.");
e1e02a22 76 bt_ctf_object_put_ref(event_class->payload_field_type);
16ca5ff0
PP
77}
78
79BT_HIDDEN
80int bt_ctf_event_class_common_initialize(struct bt_ctf_event_class_common *event_class,
e1e02a22 81 const char *name, bt_ctf_object_release_func release_func,
16ca5ff0
PP
82 bt_ctf_field_type_structure_create_func ft_struct_create_func)
83{
84 int ret = 0;
85
86 BT_LOGD("Initializing common event class object: name=\"%s\"",
87 name);
e1e02a22 88 bt_ctf_object_init_shared_with_parent(&event_class->base, release_func);
16ca5ff0
PP
89 event_class->payload_field_type = ft_struct_create_func();
90 if (!event_class->payload_field_type) {
91 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
92 goto error;
93 }
94
95 event_class->id = -1;
96 event_class->name = g_string_new(name);
97 if (!event_class->name) {
98 BT_LOGE_STR("Failed to allocate a GString.");
99 goto error;
100 }
101
102 event_class->emf_uri = g_string_new(NULL);
103 if (!event_class->emf_uri) {
104 BT_LOGE_STR("Failed to allocate a GString.");
105 goto error;
106 }
107
108 event_class->log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED;
109 BT_LOGD("Initialized common event class object: addr=%p, name=\"%s\"",
110 event_class, bt_ctf_event_class_common_get_name(event_class));
111 return ret;
112
113error:
114 ret = -1;
115 return ret;
116}
117
118BT_HIDDEN
119void bt_ctf_event_class_common_freeze(struct bt_ctf_event_class_common *event_class)
120{
121 BT_ASSERT(event_class);
122
123 if (event_class->frozen) {
124 return;
125 }
126
127 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64,
128 event_class, bt_ctf_event_class_common_get_name(event_class),
129 bt_ctf_event_class_common_get_id(event_class));
130 event_class->frozen = 1;
131 BT_LOGD_STR("Freezing event class's context field type.");
132 bt_ctf_field_type_common_freeze(event_class->context_field_type);
133 BT_LOGD_STR("Freezing event class's payload field type.");
134 bt_ctf_field_type_common_freeze(event_class->payload_field_type);
135}
136
137BT_HIDDEN
138int bt_ctf_event_class_common_validate_single_clock_class(
139 struct bt_ctf_event_class_common *event_class,
140 struct bt_ctf_clock_class **expected_clock_class)
141{
142 int ret = 0;
143
144 BT_ASSERT(event_class);
145 BT_ASSERT(expected_clock_class);
146 ret = bt_ctf_field_type_common_validate_single_clock_class(
147 event_class->context_field_type,
148 expected_clock_class);
149 if (ret) {
150 BT_LOGW("Event class's context field type "
151 "is not recursively mapped to the "
152 "expected clock class: "
153 "event-class-addr=%p, "
154 "event-class-name=\"%s\", "
155 "event-class-id=%" PRId64 ", "
156 "ft-addr=%p",
157 event_class,
158 bt_ctf_event_class_common_get_name(event_class),
159 event_class->id,
160 event_class->context_field_type);
161 goto end;
162 }
163
164 ret = bt_ctf_field_type_common_validate_single_clock_class(
165 event_class->payload_field_type,
166 expected_clock_class);
167 if (ret) {
168 BT_LOGW("Event class's payload field type "
169 "is not recursively mapped to the "
170 "expected clock class: "
171 "event-class-addr=%p, "
172 "event-class-name=\"%s\", "
173 "event-class-id=%" PRId64 ", "
174 "ft-addr=%p",
175 event_class,
176 bt_ctf_event_class_common_get_name(event_class),
177 event_class->id,
178 event_class->payload_field_type);
179 goto end;
180 }
181
182end:
183 return ret;
184}
3dca2276
PP
185
186static
e1e02a22 187void bt_ctf_event_class_destroy(struct bt_ctf_object *obj)
3dca2276 188{
16ca5ff0 189 bt_ctf_event_class_common_finalize(obj);
3dca2276
PP
190 g_free(obj);
191}
192
193struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
194{
195 struct bt_ctf_event_class *ctf_event_class = NULL;
196 int ret;
197
198 if (!name) {
199 BT_LOGW_STR("Invalid parameter: name is NULL.");
200 goto error;
201 }
202
203 BT_LOGD("Creating event class object: name=\"%s\"",
204 name);
205 ctf_event_class = g_new0(struct bt_ctf_event_class, 1);
206 if (!ctf_event_class) {
207 BT_LOGE_STR("Failed to allocate one event class.");
208 goto error;
209 }
210
16ca5ff0 211 ret = bt_ctf_event_class_common_initialize(BT_CTF_TO_COMMON(ctf_event_class),
3dca2276 212 name, bt_ctf_event_class_destroy,
16ca5ff0 213 (bt_ctf_field_type_structure_create_func)
3dca2276
PP
214 bt_ctf_field_type_structure_create);
215 if (ret) {
216 goto error;
217 }
218
219 goto end;
220
221error:
e1e02a22 222 bt_ctf_object_put_ref(ctf_event_class);
3dca2276
PP
223
224end:
225 return ctf_event_class;
226}
227
228const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
229{
16ca5ff0 230 return bt_ctf_event_class_common_get_name(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
231}
232
233int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
234{
16ca5ff0 235 return bt_ctf_event_class_common_get_id(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
236}
237
238int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
239 uint64_t id)
240{
16ca5ff0 241 return bt_ctf_event_class_common_set_id(BT_CTF_TO_COMMON(event_class), id);
3dca2276
PP
242}
243
244enum bt_ctf_event_class_log_level bt_ctf_event_class_get_log_level(
245 struct bt_ctf_event_class *event_class)
246{
16ca5ff0 247 return bt_ctf_event_class_common_get_log_level(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
248}
249
250int bt_ctf_event_class_set_log_level(struct bt_ctf_event_class *event_class,
251 enum bt_ctf_event_class_log_level log_level)
252{
16ca5ff0 253 return bt_ctf_event_class_common_set_log_level(BT_CTF_TO_COMMON(event_class),
3dca2276
PP
254 log_level);
255}
256
257const char *bt_ctf_event_class_get_emf_uri(
258 struct bt_ctf_event_class *event_class)
259{
16ca5ff0 260 return bt_ctf_event_class_common_get_emf_uri(BT_CTF_TO_COMMON(event_class));
3dca2276
PP
261}
262
263int bt_ctf_event_class_set_emf_uri(struct bt_ctf_event_class *event_class,
264 const char *emf_uri)
265{
16ca5ff0 266 return bt_ctf_event_class_common_set_emf_uri(BT_CTF_TO_COMMON(event_class),
3dca2276
PP
267 emf_uri);
268}
269
270struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
271 struct bt_ctf_event_class *event_class)
272{
67d2ce02 273 BT_CTF_ASSERT_PRE_NON_NULL(event_class, "Event class");
e1e02a22 274 return bt_ctf_object_get_ref(bt_ctf_event_class_common_borrow_stream_class(
16ca5ff0 275 BT_CTF_TO_COMMON(event_class)));
3dca2276
PP
276}
277
278struct bt_ctf_field_type *bt_ctf_event_class_get_payload_field_type(
279 struct bt_ctf_event_class *event_class)
280{
e1e02a22 281 return bt_ctf_object_get_ref(bt_ctf_event_class_common_borrow_payload_field_type(
16ca5ff0 282 BT_CTF_TO_COMMON(event_class)));
3dca2276
PP
283}
284
285int bt_ctf_event_class_set_payload_field_type(
286 struct bt_ctf_event_class *event_class,
287 struct bt_ctf_field_type *field_type)
288{
16ca5ff0
PP
289 return bt_ctf_event_class_common_set_payload_field_type(
290 BT_CTF_TO_COMMON(event_class), (void *) field_type);
3dca2276
PP
291}
292
293struct bt_ctf_field_type *bt_ctf_event_class_get_context_field_type(
294 struct bt_ctf_event_class *event_class)
295{
e1e02a22 296 return bt_ctf_object_get_ref(bt_ctf_event_class_common_borrow_context_field_type(
16ca5ff0 297 BT_CTF_TO_COMMON(event_class)));
3dca2276
PP
298}
299
300int bt_ctf_event_class_set_context_field_type(
301 struct bt_ctf_event_class *event_class,
302 struct bt_ctf_field_type *field_type)
303{
16ca5ff0
PP
304 return bt_ctf_event_class_common_set_context_field_type(
305 BT_CTF_TO_COMMON(event_class), (void *) field_type);
3dca2276
PP
306}
307
308int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
309 struct bt_ctf_field_type *type,
310 const char *name)
311{
312 int ret = 0;
313
314 if (!event_class || !type) {
315 BT_LOGW("Invalid parameter: event class or field type is NULL: "
316 "event-class-addr=%p, field-type-addr=%p",
317 event_class, type);
318 ret = -1;
319 goto end;
320 }
321
16ca5ff0 322 if (!bt_ctf_identifier_is_valid(name)) {
3dca2276
PP
323 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
324 "addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"",
325 event_class, bt_ctf_event_class_get_name(event_class),
326 bt_ctf_event_class_get_id(event_class),
327 name);
328 ret = -1;
329 goto end;
330 }
331
332 if (event_class->common.frozen) {
333 BT_LOGW("Invalid parameter: event class is frozen: "
334 "addr=%p, name=\"%s\", id=%" PRId64,
335 event_class, bt_ctf_event_class_get_name(event_class),
336 bt_ctf_event_class_get_id(event_class));
337 ret = -1;
338 goto end;
339 }
340
341 if (!event_class->common.payload_field_type) {
342 BT_LOGW("Event class has no payload field type: "
343 "addr=%p, name=\"%s\", id=%" PRId64,
344 event_class, bt_ctf_event_class_get_name(event_class),
345 bt_ctf_event_class_get_id(event_class));
346 ret = -1;
347 goto end;
348 }
349
16ca5ff0 350 BT_ASSERT(bt_ctf_field_type_common_get_type_id(
3dca2276 351 event_class->common.payload_field_type) ==
16ca5ff0 352 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
353 ret = bt_ctf_field_type_structure_add_field(
354 (void *) event_class->common.payload_field_type,
355 (void *) type, name);
ef267d12 356 BT_LOGT("Added field to event class's payload field type: "
3dca2276
PP
357 "event-class-addr=%p, event-class-name=\"%s\", "
358 "event-class-id=%" PRId64 ", field-name=\"%s\", ft-addr=%p",
359 event_class, bt_ctf_event_class_get_name(event_class),
360 bt_ctf_event_class_get_id(event_class), name, type);
361end:
362 return ret;
363}
364
365int64_t bt_ctf_event_class_get_payload_type_field_count(
366 struct bt_ctf_event_class *event_class)
367{
368 int64_t ret;
369
370 if (!event_class) {
371 BT_LOGW_STR("Invalid parameter: event class is NULL.");
372 ret = (int64_t) -1;
373 goto end;
374 }
375
376 if (!event_class->common.payload_field_type) {
ef267d12 377 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
378 "addr=%p, name=\"%s\", id=%" PRId64,
379 event_class, bt_ctf_event_class_get_name(event_class),
380 bt_ctf_event_class_get_id(event_class));
381 ret = (int64_t) -1;
382 goto end;
383 }
384
16ca5ff0 385 BT_ASSERT(bt_ctf_field_type_common_get_type_id(
3dca2276 386 event_class->common.payload_field_type) ==
16ca5ff0
PP
387 BT_CTF_FIELD_TYPE_ID_STRUCT);
388 ret = bt_ctf_field_type_common_structure_get_field_count(
3dca2276
PP
389 event_class->common.payload_field_type);
390end:
391 return ret;
392}
393
394int bt_ctf_event_class_get_payload_type_field_by_index(
395 struct bt_ctf_event_class *event_class,
396 const char **field_name, struct bt_ctf_field_type **field_type,
397 uint64_t index)
398{
399 int ret;
400
401 if (!event_class) {
402 BT_LOGW_STR("Invalid parameter: event class is NULL.");
403 ret = -1;
404 goto end;
405 }
406
407 if (!event_class->common.payload_field_type) {
ef267d12 408 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
409 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
410 event_class, bt_ctf_event_class_get_name(event_class),
411 bt_ctf_event_class_get_id(event_class), index);
412 ret = -1;
413 goto end;
414 }
415
16ca5ff0 416 BT_ASSERT(bt_ctf_field_type_common_get_type_id(
3dca2276 417 event_class->common.payload_field_type) ==
16ca5ff0 418 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
419 ret = bt_ctf_field_type_structure_get_field_by_index(
420 (void *) event_class->common.payload_field_type,
421 field_name, (void *) field_type, index);
422
423end:
424 return ret;
425}
426
16ca5ff0 427struct bt_ctf_field_type *
3dca2276
PP
428bt_ctf_event_class_get_payload_type_field_type_by_name(
429 struct bt_ctf_event_class *event_class, const char *name)
430{
431 GQuark name_quark;
16ca5ff0 432 struct bt_ctf_field_type *field_type = NULL;
3dca2276
PP
433
434 if (!event_class || !name) {
435 BT_LOGW("Invalid parameter: event class or name is NULL: "
436 "event-class-addr=%p, name-addr=%p",
437 event_class, name);
438 goto end;
439 }
440
441 if (!event_class->common.payload_field_type) {
ef267d12 442 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
443 "addr=%p, name=\"%s\", id=%" PRId64,
444 event_class, bt_ctf_event_class_get_name(event_class),
445 bt_ctf_event_class_get_id(event_class));
446 goto end;
447 }
448
16ca5ff0 449 BT_ASSERT(bt_ctf_field_type_common_get_type_id(
3dca2276 450 event_class->common.payload_field_type) ==
16ca5ff0 451 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
452 name_quark = g_quark_try_string(name);
453 if (!name_quark) {
454 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
455 goto end;
456 }
457
458 /*
459 * No need to increment field_type's reference count since getting it
460 * from the structure already does.
461 */
462 field_type = (void *)
463 bt_ctf_field_type_structure_get_field_type_by_name(
464 (void *) event_class->common.payload_field_type, name);
465
466end:
467 return field_type;
468}
469
470BT_HIDDEN
471int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
472 struct metadata_context *context)
473{
474 int ret = 0;
e1e02a22 475 struct bt_ctf_value *attr_value = NULL;
3dca2276
PP
476
477 BT_ASSERT(event_class);
478 BT_ASSERT(context);
479 BT_LOGD("Serializing event class's metadata: "
480 "event-class-addr=%p, event-class-name=\"%s\", "
481 "event-class-id=%" PRId64 ", metadata-context-addr=%p",
482 event_class, bt_ctf_event_class_get_name(event_class),
483 bt_ctf_event_class_get_id(event_class), context);
484 context->current_indentation_level = 1;
485 g_string_assign(context->field_name, "");
486 g_string_append(context->string, "event {\n");
487
488 /* Serialize attributes */
489 g_string_append_printf(context->string, "\tname = \"%s\";\n",
490 event_class->common.name->str);
491 BT_ASSERT(event_class->common.id >= 0);
492 g_string_append_printf(context->string, "\tid = %" PRId64 ";\n",
493 event_class->common.id);
494 g_string_append_printf(context->string, "\tstream_id = %" PRId64 ";\n",
16ca5ff0
PP
495 bt_ctf_stream_class_common_get_id(
496 bt_ctf_event_class_common_borrow_stream_class(
497 BT_CTF_TO_COMMON(event_class))));
3dca2276
PP
498
499 if (event_class->common.log_level !=
16ca5ff0 500 BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
3dca2276
PP
501 g_string_append_printf(context->string, "\tloglevel = %d;\n",
502 (int) event_class->common.log_level);
503 }
504
505 if (event_class->common.emf_uri->len > 0) {
506 g_string_append_printf(context->string, "\tmodel.emf.uri = \"%s\";\n",
507 event_class->common.emf_uri->str);
508 }
509
510 /* Serialize context field type */
511 if (event_class->common.context_field_type) {
512 g_string_append(context->string, "\tcontext := ");
513 BT_LOGD_STR("Serializing event class's context field type metadata.");
514 ret = bt_ctf_field_type_serialize_recursive(
515 (void *) event_class->common.context_field_type,
516 context);
517 if (ret) {
518 BT_LOGW("Cannot serialize event class's context field type's metadata: "
519 "ret=%d", ret);
520 goto end;
521 }
522 g_string_append(context->string, ";\n");
523 }
524
525 /* Serialize payload field type */
526 if (event_class->common.payload_field_type) {
527 g_string_append(context->string, "\tfields := ");
528 BT_LOGD_STR("Serializing event class's payload field type metadata.");
529 ret = bt_ctf_field_type_serialize_recursive(
530 (void *) event_class->common.payload_field_type,
531 context);
532 if (ret) {
533 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
534 "ret=%d", ret);
535 goto end;
536 }
537 g_string_append(context->string, ";\n");
538 }
539
540 g_string_append(context->string, "};\n\n");
541
542end:
543 context->current_indentation_level = 0;
e1e02a22 544 BT_CTF_OBJECT_PUT_REF_AND_RESET(attr_value);
3dca2276
PP
545 return ret;
546}
547
548struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
549 struct bt_ctf_event_class *event_class, const char *name)
550{
551 GQuark name_quark;
552 struct bt_ctf_field_type *field_type = NULL;
553
554 if (!event_class || !name) {
555 BT_LOGW("Invalid parameter: event class or name is NULL: "
556 "event-class-addr=%p, name-addr=%p",
557 event_class, name);
558 goto end;
559 }
560
561 if (!event_class->common.payload_field_type) {
ef267d12 562 BT_LOGT("Event class has no payload field type: "
3dca2276
PP
563 "addr=%p, name=\"%s\", id=%" PRId64,
564 event_class,
565 bt_ctf_event_class_get_name(event_class),
566 bt_ctf_event_class_get_id(event_class));
567 goto end;
568 }
569
570 BT_ASSERT(event_class->common.payload_field_type->id ==
16ca5ff0 571 BT_CTF_FIELD_TYPE_ID_STRUCT);
3dca2276
PP
572 name_quark = g_quark_try_string(name);
573 if (!name_quark) {
574 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
575 goto end;
576 }
577
578 /*
579 * No need to increment field_type's reference count since getting it
580 * from the structure already does.
581 */
e1e02a22 582 field_type = bt_ctf_object_get_ref(
16ca5ff0 583 bt_ctf_field_type_common_structure_borrow_field_type_by_name(
094ff7c0 584 event_class->common.payload_field_type, name));
3dca2276
PP
585
586end:
587 return field_type;
588}
This page took 0.067192 seconds and 4 git commands to generate.