2 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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
24 #define BT_LOG_TAG "CTF-WRITER-EVENT-CLASS"
25 #include <babeltrace/lib-logging-internal.h>
27 #include <babeltrace/ctf-ir/event-class-internal.h>
28 #include <babeltrace/ctf-ir/utils.h>
29 #include <babeltrace/ctf-writer/event.h>
30 #include <babeltrace/ctf-writer/event-internal.h>
31 #include <babeltrace/ctf-writer/field-types.h>
32 #include <babeltrace/ctf-writer/field-types-internal.h>
33 #include <babeltrace/ctf-writer/writer-internal.h>
34 #include <babeltrace/ref.h>
35 #include <babeltrace/compiler-internal.h>
36 #include <babeltrace/assert-internal.h>
37 #include <babeltrace/assert-pre-internal.h>
42 void bt_ctf_event_class_destroy(struct bt_object
*obj
)
44 bt_event_class_common_finalize(obj
);
48 struct bt_ctf_event_class
*bt_ctf_event_class_create(const char *name
)
50 struct bt_ctf_event_class
*ctf_event_class
= NULL
;
54 BT_LOGW_STR("Invalid parameter: name is NULL.");
58 BT_LOGD("Creating event class object: name=\"%s\"",
60 ctf_event_class
= g_new0(struct bt_ctf_event_class
, 1);
61 if (!ctf_event_class
) {
62 BT_LOGE_STR("Failed to allocate one event class.");
66 ret
= bt_event_class_common_initialize(BT_TO_COMMON(ctf_event_class
),
67 name
, bt_ctf_event_class_destroy
,
68 (bt_field_type_structure_create_func
)
69 bt_ctf_field_type_structure_create
);
77 bt_put(ctf_event_class
);
80 return ctf_event_class
;
83 const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class
*event_class
)
85 return bt_event_class_common_get_name(BT_TO_COMMON(event_class
));
88 int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class
*event_class
)
90 return bt_event_class_common_get_id(BT_TO_COMMON(event_class
));
93 int bt_ctf_event_class_set_id(struct bt_ctf_event_class
*event_class
,
96 return bt_event_class_common_set_id(BT_TO_COMMON(event_class
), id
);
99 enum bt_ctf_event_class_log_level
bt_ctf_event_class_get_log_level(
100 struct bt_ctf_event_class
*event_class
)
102 return bt_event_class_common_get_log_level(BT_TO_COMMON(event_class
));
105 int bt_ctf_event_class_set_log_level(struct bt_ctf_event_class
*event_class
,
106 enum bt_ctf_event_class_log_level log_level
)
108 return bt_event_class_common_set_log_level(BT_TO_COMMON(event_class
),
112 const char *bt_ctf_event_class_get_emf_uri(
113 struct bt_ctf_event_class
*event_class
)
115 return bt_event_class_common_get_emf_uri(BT_TO_COMMON(event_class
));
118 int bt_ctf_event_class_set_emf_uri(struct bt_ctf_event_class
*event_class
,
121 return bt_event_class_common_set_emf_uri(BT_TO_COMMON(event_class
),
125 struct bt_ctf_stream_class
*bt_ctf_event_class_get_stream_class(
126 struct bt_ctf_event_class
*event_class
)
128 BT_ASSERT_PRE_NON_NULL(event_class
, "Event class");
129 return bt_get(bt_event_class_common_borrow_stream_class(
130 BT_TO_COMMON(event_class
)));
133 struct bt_ctf_field_type
*bt_ctf_event_class_get_payload_field_type(
134 struct bt_ctf_event_class
*event_class
)
136 return bt_get(bt_event_class_common_borrow_payload_field_type(
137 BT_TO_COMMON(event_class
)));
140 int bt_ctf_event_class_set_payload_field_type(
141 struct bt_ctf_event_class
*event_class
,
142 struct bt_ctf_field_type
*field_type
)
144 return bt_event_class_common_set_payload_field_type(
145 BT_TO_COMMON(event_class
), (void *) field_type
);
148 struct bt_ctf_field_type
*bt_ctf_event_class_get_context_field_type(
149 struct bt_ctf_event_class
*event_class
)
151 return bt_get(bt_event_class_common_borrow_context_field_type(
152 BT_TO_COMMON(event_class
)));
155 int bt_ctf_event_class_set_context_field_type(
156 struct bt_ctf_event_class
*event_class
,
157 struct bt_ctf_field_type
*field_type
)
159 return bt_event_class_common_set_context_field_type(
160 BT_TO_COMMON(event_class
), (void *) field_type
);
163 int bt_ctf_event_class_add_field(struct bt_ctf_event_class
*event_class
,
164 struct bt_ctf_field_type
*type
,
169 if (!event_class
|| !type
) {
170 BT_LOGW("Invalid parameter: event class or field type is NULL: "
171 "event-class-addr=%p, field-type-addr=%p",
177 if (!bt_identifier_is_valid(name
)) {
178 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
179 "addr=%p, name=\"%s\", id=%" PRId64
", field-name=\"%s\"",
180 event_class
, bt_ctf_event_class_get_name(event_class
),
181 bt_ctf_event_class_get_id(event_class
),
187 if (event_class
->common
.frozen
) {
188 BT_LOGW("Invalid parameter: event class is frozen: "
189 "addr=%p, name=\"%s\", id=%" PRId64
,
190 event_class
, bt_ctf_event_class_get_name(event_class
),
191 bt_ctf_event_class_get_id(event_class
));
196 if (!event_class
->common
.payload_field_type
) {
197 BT_LOGW("Event class has no payload field type: "
198 "addr=%p, name=\"%s\", id=%" PRId64
,
199 event_class
, bt_ctf_event_class_get_name(event_class
),
200 bt_ctf_event_class_get_id(event_class
));
205 BT_ASSERT(bt_field_type_common_get_type_id(
206 event_class
->common
.payload_field_type
) ==
207 BT_FIELD_TYPE_ID_STRUCT
);
208 ret
= bt_ctf_field_type_structure_add_field(
209 (void *) event_class
->common
.payload_field_type
,
210 (void *) type
, name
);
211 BT_LOGV("Added field to event class's payload field type: "
212 "event-class-addr=%p, event-class-name=\"%s\", "
213 "event-class-id=%" PRId64
", field-name=\"%s\", ft-addr=%p",
214 event_class
, bt_ctf_event_class_get_name(event_class
),
215 bt_ctf_event_class_get_id(event_class
), name
, type
);
220 int64_t bt_ctf_event_class_get_payload_type_field_count(
221 struct bt_ctf_event_class
*event_class
)
226 BT_LOGW_STR("Invalid parameter: event class is NULL.");
231 if (!event_class
->common
.payload_field_type
) {
232 BT_LOGV("Event class has no payload field type: "
233 "addr=%p, name=\"%s\", id=%" PRId64
,
234 event_class
, bt_ctf_event_class_get_name(event_class
),
235 bt_ctf_event_class_get_id(event_class
));
240 BT_ASSERT(bt_field_type_common_get_type_id(
241 event_class
->common
.payload_field_type
) ==
242 BT_FIELD_TYPE_ID_STRUCT
);
243 ret
= bt_field_type_common_structure_get_field_count(
244 event_class
->common
.payload_field_type
);
249 int bt_ctf_event_class_get_payload_type_field_by_index(
250 struct bt_ctf_event_class
*event_class
,
251 const char **field_name
, struct bt_ctf_field_type
**field_type
,
257 BT_LOGW_STR("Invalid parameter: event class is NULL.");
262 if (!event_class
->common
.payload_field_type
) {
263 BT_LOGV("Event class has no payload field type: "
264 "addr=%p, name=\"%s\", id=%" PRId64
", index=%" PRIu64
,
265 event_class
, bt_ctf_event_class_get_name(event_class
),
266 bt_ctf_event_class_get_id(event_class
), index
);
271 BT_ASSERT(bt_field_type_common_get_type_id(
272 event_class
->common
.payload_field_type
) ==
273 BT_FIELD_TYPE_ID_STRUCT
);
274 ret
= bt_ctf_field_type_structure_get_field_by_index(
275 (void *) event_class
->common
.payload_field_type
,
276 field_name
, (void *) field_type
, index
);
282 struct bt_field_type
*
283 bt_ctf_event_class_get_payload_type_field_type_by_name(
284 struct bt_ctf_event_class
*event_class
, const char *name
)
287 struct bt_field_type
*field_type
= NULL
;
289 if (!event_class
|| !name
) {
290 BT_LOGW("Invalid parameter: event class or name is NULL: "
291 "event-class-addr=%p, name-addr=%p",
296 if (!event_class
->common
.payload_field_type
) {
297 BT_LOGV("Event class has no payload field type: "
298 "addr=%p, name=\"%s\", id=%" PRId64
,
299 event_class
, bt_ctf_event_class_get_name(event_class
),
300 bt_ctf_event_class_get_id(event_class
));
304 BT_ASSERT(bt_field_type_common_get_type_id(
305 event_class
->common
.payload_field_type
) ==
306 BT_FIELD_TYPE_ID_STRUCT
);
307 name_quark
= g_quark_try_string(name
);
309 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
314 * No need to increment field_type's reference count since getting it
315 * from the structure already does.
317 field_type
= (void *)
318 bt_ctf_field_type_structure_get_field_type_by_name(
319 (void *) event_class
->common
.payload_field_type
, name
);
326 int bt_ctf_event_class_serialize(struct bt_ctf_event_class
*event_class
,
327 struct metadata_context
*context
)
330 struct bt_value
*attr_value
= NULL
;
332 BT_ASSERT(event_class
);
334 BT_LOGD("Serializing event class's metadata: "
335 "event-class-addr=%p, event-class-name=\"%s\", "
336 "event-class-id=%" PRId64
", metadata-context-addr=%p",
337 event_class
, bt_ctf_event_class_get_name(event_class
),
338 bt_ctf_event_class_get_id(event_class
), context
);
339 context
->current_indentation_level
= 1;
340 g_string_assign(context
->field_name
, "");
341 g_string_append(context
->string
, "event {\n");
343 /* Serialize attributes */
344 g_string_append_printf(context
->string
, "\tname = \"%s\";\n",
345 event_class
->common
.name
->str
);
346 BT_ASSERT(event_class
->common
.id
>= 0);
347 g_string_append_printf(context
->string
, "\tid = %" PRId64
";\n",
348 event_class
->common
.id
);
349 g_string_append_printf(context
->string
, "\tstream_id = %" PRId64
";\n",
350 bt_stream_class_common_get_id(
351 bt_event_class_common_borrow_stream_class(
352 BT_TO_COMMON(event_class
))));
354 if (event_class
->common
.log_level
!=
355 BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
) {
356 g_string_append_printf(context
->string
, "\tloglevel = %d;\n",
357 (int) event_class
->common
.log_level
);
360 if (event_class
->common
.emf_uri
->len
> 0) {
361 g_string_append_printf(context
->string
, "\tmodel.emf.uri = \"%s\";\n",
362 event_class
->common
.emf_uri
->str
);
365 /* Serialize context field type */
366 if (event_class
->common
.context_field_type
) {
367 g_string_append(context
->string
, "\tcontext := ");
368 BT_LOGD_STR("Serializing event class's context field type metadata.");
369 ret
= bt_ctf_field_type_serialize_recursive(
370 (void *) event_class
->common
.context_field_type
,
373 BT_LOGW("Cannot serialize event class's context field type's metadata: "
377 g_string_append(context
->string
, ";\n");
380 /* Serialize payload field type */
381 if (event_class
->common
.payload_field_type
) {
382 g_string_append(context
->string
, "\tfields := ");
383 BT_LOGD_STR("Serializing event class's payload field type metadata.");
384 ret
= bt_ctf_field_type_serialize_recursive(
385 (void *) event_class
->common
.payload_field_type
,
388 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
392 g_string_append(context
->string
, ";\n");
395 g_string_append(context
->string
, "};\n\n");
398 context
->current_indentation_level
= 0;
403 struct bt_ctf_field_type
*bt_ctf_event_class_get_field_by_name(
404 struct bt_ctf_event_class
*event_class
, const char *name
)
407 struct bt_ctf_field_type
*field_type
= NULL
;
409 if (!event_class
|| !name
) {
410 BT_LOGW("Invalid parameter: event class or name is NULL: "
411 "event-class-addr=%p, name-addr=%p",
416 if (!event_class
->common
.payload_field_type
) {
417 BT_LOGV("Event class has no payload field type: "
418 "addr=%p, name=\"%s\", id=%" PRId64
,
420 bt_ctf_event_class_get_name(event_class
),
421 bt_ctf_event_class_get_id(event_class
));
425 BT_ASSERT(event_class
->common
.payload_field_type
->id
==
426 BT_FIELD_TYPE_ID_STRUCT
);
427 name_quark
= g_quark_try_string(name
);
429 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
434 * No need to increment field_type's reference count since getting it
435 * from the structure already does.
438 bt_field_type_common_structure_borrow_field_type_by_name(
439 event_class
->common
.payload_field_type
, name
));