Commit | Line | Data |
---|---|---|
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> | |
8c4a29ba | 41 | #include <babeltrace/ctf-ir/utils-internal.h> |
272df73e PP |
42 | #include <babeltrace/ref.h> |
43 | #include <babeltrace/ctf-ir/attributes-internal.h> | |
3d9990ac PP |
44 | #include <babeltrace/compiler-internal.h> |
45 | #include <babeltrace/endian-internal.h> | |
c55a9f58 | 46 | #include <babeltrace/types.h> |
f8b979f9 | 47 | #include <babeltrace/values-internal.h> |
8b45963b | 48 | #include <babeltrace/assert-internal.h> |
44ea72c5 | 49 | #include <babeltrace/assert-pre-internal.h> |
dc3fffef | 50 | #include <inttypes.h> |
0fbb9a9f | 51 | #include <stdlib.h> |
272df73e PP |
52 | |
53 | static | |
839d52a5 | 54 | void bt_event_class_destroy(struct bt_object *obj); |
272df73e | 55 | |
839d52a5 | 56 | struct bt_event_class *bt_event_class_create(const char *name) |
272df73e | 57 | { |
272df73e | 58 | struct bt_value *obj = NULL; |
839d52a5 | 59 | struct bt_event_class *event_class = NULL; |
272df73e | 60 | |
f8b979f9 PP |
61 | BT_LOGD("Creating event class object: name=\"%s\"", |
62 | name); | |
63 | ||
9cf5d083 PP |
64 | if (!name) { |
65 | BT_LOGW_STR("Invalid parameter: name is NULL."); | |
66 | goto error; | |
67 | } | |
68 | ||
839d52a5 | 69 | event_class = g_new0(struct bt_event_class, 1); |
272df73e | 70 | if (!event_class) { |
f8b979f9 | 71 | BT_LOGE_STR("Failed to allocate one event class."); |
272df73e PP |
72 | goto error; |
73 | } | |
74 | ||
839d52a5 PP |
75 | bt_object_init(event_class, bt_event_class_destroy); |
76 | event_class->fields = bt_field_type_structure_create(); | |
272df73e | 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 | ||
9cf5d083 PP |
82 | event_class->id = -1; |
83 | event_class->name = g_string_new(name); | |
84 | if (!event_class->name) { | |
85 | BT_LOGE_STR("Failed to allocate a GString."); | |
272df73e PP |
86 | goto error; |
87 | } | |
88 | ||
9cf5d083 PP |
89 | event_class->emf_uri = g_string_new(NULL); |
90 | if (!event_class->emf_uri) { | |
91 | BT_LOGE_STR("Failed to allocate a GString."); | |
272df73e PP |
92 | goto error; |
93 | } | |
94 | ||
839d52a5 | 95 | event_class->log_level = BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED; |
272df73e | 96 | BT_PUT(obj); |
f8b979f9 | 97 | BT_LOGD("Created event class object: addr=%p, name=\"%s\"", |
839d52a5 | 98 | event_class, bt_event_class_get_name(event_class)); |
272df73e PP |
99 | return event_class; |
100 | ||
101 | error: | |
102 | BT_PUT(event_class); | |
103 | BT_PUT(obj); | |
104 | return event_class; | |
105 | } | |
106 | ||
839d52a5 | 107 | const char *bt_event_class_get_name(struct bt_event_class *event_class) |
272df73e | 108 | { |
44ea72c5 PP |
109 | BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); |
110 | BT_ASSERT(event_class->name); | |
111 | return event_class->name->str; | |
272df73e PP |
112 | } |
113 | ||
839d52a5 | 114 | int64_t bt_event_class_get_id(struct bt_event_class *event_class) |
272df73e | 115 | { |
44ea72c5 PP |
116 | BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); |
117 | return event_class->id; | |
272df73e PP |
118 | } |
119 | ||
839d52a5 | 120 | int bt_event_class_set_id(struct bt_event_class *event_class, |
9ac68eb1 | 121 | uint64_t id_param) |
272df73e PP |
122 | { |
123 | int ret = 0; | |
9ac68eb1 | 124 | int64_t id = (int64_t) id_param; |
272df73e | 125 | |
f8b979f9 PP |
126 | if (!event_class) { |
127 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
272df73e PP |
128 | ret = -1; |
129 | goto end; | |
130 | } | |
131 | ||
f8b979f9 PP |
132 | if (event_class->frozen) { |
133 | BT_LOGW("Invalid parameter: event class is frozen: " | |
134 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
135 | event_class, bt_event_class_get_name(event_class), |
136 | bt_event_class_get_id(event_class)); | |
272df73e PP |
137 | ret = -1; |
138 | goto end; | |
139 | } | |
140 | ||
f8b979f9 PP |
141 | if (id < 0) { |
142 | BT_LOGW("Invalid parameter: invalid event class's ID: " | |
143 | "addr=%p, name=\"%s\", id=%" PRIu64, | |
839d52a5 | 144 | event_class, bt_event_class_get_name(event_class), |
f8b979f9 | 145 | id_param); |
272df73e PP |
146 | ret = -1; |
147 | goto end; | |
148 | } | |
149 | ||
9cf5d083 | 150 | event_class->id = id; |
f8b979f9 PP |
151 | BT_LOGV("Set event class's ID: " |
152 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 | 153 | event_class, bt_event_class_get_name(event_class), id); |
f8b979f9 | 154 | |
272df73e | 155 | end: |
272df73e PP |
156 | return ret; |
157 | } | |
158 | ||
839d52a5 PP |
159 | enum bt_event_class_log_level bt_event_class_get_log_level( |
160 | struct bt_event_class *event_class) | |
9cf5d083 | 161 | { |
44ea72c5 PP |
162 | BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); |
163 | return event_class->log_level; | |
9cf5d083 PP |
164 | } |
165 | ||
839d52a5 PP |
166 | int bt_event_class_set_log_level(struct bt_event_class *event_class, |
167 | enum bt_event_class_log_level log_level) | |
272df73e PP |
168 | { |
169 | int ret = 0; | |
170 | ||
9cf5d083 PP |
171 | if (!event_class) { |
172 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
f8b979f9 PP |
173 | ret = -1; |
174 | goto end; | |
175 | } | |
176 | ||
177 | if (event_class->frozen) { | |
178 | BT_LOGW("Invalid parameter: event class is frozen: " | |
9cf5d083 | 179 | "addr=%p, name=\"%s\", id=%" PRId64, |
839d52a5 PP |
180 | event_class, bt_event_class_get_name(event_class), |
181 | bt_event_class_get_id(event_class)); | |
272df73e PP |
182 | ret = -1; |
183 | goto end; | |
184 | } | |
185 | ||
9cf5d083 | 186 | switch (log_level) { |
839d52a5 PP |
187 | case BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED: |
188 | case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY: | |
189 | case BT_EVENT_CLASS_LOG_LEVEL_ALERT: | |
190 | case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL: | |
191 | case BT_EVENT_CLASS_LOG_LEVEL_ERROR: | |
192 | case BT_EVENT_CLASS_LOG_LEVEL_WARNING: | |
193 | case BT_EVENT_CLASS_LOG_LEVEL_NOTICE: | |
194 | case BT_EVENT_CLASS_LOG_LEVEL_INFO: | |
195 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM: | |
196 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM: | |
197 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS: | |
198 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE: | |
199 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT: | |
200 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION: | |
201 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE: | |
202 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG: | |
9cf5d083 PP |
203 | break; |
204 | default: | |
205 | BT_LOGW("Invalid parameter: unknown event class log level: " | |
206 | "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%d", | |
839d52a5 PP |
207 | event_class, bt_event_class_get_name(event_class), |
208 | bt_event_class_get_id(event_class), log_level); | |
272df73e PP |
209 | ret = -1; |
210 | goto end; | |
211 | } | |
212 | ||
9cf5d083 PP |
213 | event_class->log_level = log_level; |
214 | BT_LOGV("Set event class's log level: " | |
215 | "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%s", | |
839d52a5 PP |
216 | event_class, bt_event_class_get_name(event_class), |
217 | bt_event_class_get_id(event_class), | |
218 | bt_event_class_log_level_string(log_level)); | |
272df73e PP |
219 | |
220 | end: | |
221 | return ret; | |
222 | } | |
223 | ||
839d52a5 PP |
224 | const char *bt_event_class_get_emf_uri( |
225 | struct bt_event_class *event_class) | |
272df73e | 226 | { |
9cf5d083 | 227 | const char *emf_uri = NULL; |
272df73e | 228 | |
44ea72c5 | 229 | BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); |
272df73e | 230 | |
9cf5d083 PP |
231 | if (event_class->emf_uri->len > 0) { |
232 | emf_uri = event_class->emf_uri->str; | |
233 | } | |
272df73e | 234 | |
9cf5d083 | 235 | return emf_uri; |
272df73e PP |
236 | } |
237 | ||
839d52a5 | 238 | int bt_event_class_set_emf_uri(struct bt_event_class *event_class, |
9cf5d083 | 239 | const char *emf_uri) |
272df73e | 240 | { |
9cf5d083 | 241 | int ret = 0; |
272df73e PP |
242 | |
243 | if (!event_class) { | |
f8b979f9 | 244 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
9cf5d083 | 245 | ret = -1; |
272df73e PP |
246 | goto end; |
247 | } | |
248 | ||
9cf5d083 PP |
249 | if (emf_uri && strlen(emf_uri) == 0) { |
250 | BT_LOGW_STR("Invalid parameter: EMF URI is empty."); | |
251 | ret = -1; | |
272df73e PP |
252 | goto end; |
253 | } | |
254 | ||
9cf5d083 PP |
255 | if (event_class->frozen) { |
256 | BT_LOGW("Invalid parameter: event class is frozen: " | |
257 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
258 | event_class, bt_event_class_get_name(event_class), |
259 | bt_event_class_get_id(event_class)); | |
9cf5d083 | 260 | ret = -1; |
272df73e PP |
261 | goto end; |
262 | } | |
263 | ||
9cf5d083 PP |
264 | if (emf_uri) { |
265 | g_string_assign(event_class->emf_uri, emf_uri); | |
266 | BT_LOGV("Set event class's EMF URI: " | |
267 | "addr=%p, name=\"%s\", id=%" PRId64 ", emf-uri=\"%s\"", | |
839d52a5 PP |
268 | event_class, bt_event_class_get_name(event_class), |
269 | bt_event_class_get_id(event_class), emf_uri); | |
9cf5d083 PP |
270 | } else { |
271 | g_string_assign(event_class->emf_uri, ""); | |
272 | BT_LOGV("Reset event class's EMF URI: " | |
273 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
274 | event_class, bt_event_class_get_name(event_class), |
275 | bt_event_class_get_id(event_class)); | |
f8b979f9 | 276 | } |
272df73e PP |
277 | |
278 | end: | |
279 | return ret; | |
272df73e PP |
280 | } |
281 | ||
839d52a5 PP |
282 | struct bt_stream_class *bt_event_class_get_stream_class( |
283 | struct bt_event_class *event_class) | |
272df73e | 284 | { |
44ea72c5 PP |
285 | BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); |
286 | return bt_get(bt_event_class_borrow_stream_class(event_class)); | |
272df73e PP |
287 | } |
288 | ||
839d52a5 PP |
289 | struct bt_field_type *bt_event_class_get_payload_type( |
290 | struct bt_event_class *event_class) | |
272df73e | 291 | { |
44ea72c5 PP |
292 | BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); |
293 | return bt_get(event_class->fields); | |
272df73e PP |
294 | } |
295 | ||
839d52a5 PP |
296 | int bt_event_class_set_payload_type(struct bt_event_class *event_class, |
297 | struct bt_field_type *payload) | |
272df73e PP |
298 | { |
299 | int ret = 0; | |
300 | ||
835b2d10 | 301 | if (!event_class) { |
f8b979f9 | 302 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
835b2d10 JG |
303 | ret = -1; |
304 | goto end; | |
305 | } | |
306 | ||
839d52a5 PP |
307 | if (payload && bt_field_type_get_type_id(payload) != |
308 | BT_FIELD_TYPE_ID_STRUCT) { | |
f8b979f9 PP |
309 | BT_LOGW("Invalid parameter: event class's payload field type must be a structure: " |
310 | "addr=%p, name=\"%s\", id=%" PRId64 ", " | |
311 | "payload-ft-addr=%p, payload-ft-id=%s", | |
839d52a5 PP |
312 | event_class, bt_event_class_get_name(event_class), |
313 | bt_event_class_get_id(event_class), payload, | |
314 | bt_field_type_id_string( | |
315 | bt_field_type_get_type_id(payload))); | |
272df73e PP |
316 | ret = -1; |
317 | goto end; | |
318 | } | |
319 | ||
272df73e | 320 | bt_put(event_class->fields); |
835b2d10 | 321 | event_class->fields = bt_get(payload); |
f8b979f9 PP |
322 | BT_LOGV("Set event class's payload field type: " |
323 | "event-class-addr=%p, event-class-name=\"%s\", " | |
324 | "event-class-id=%" PRId64 ", payload-ft-addr=%p", | |
839d52a5 PP |
325 | event_class, bt_event_class_get_name(event_class), |
326 | bt_event_class_get_id(event_class), payload); | |
272df73e PP |
327 | end: |
328 | return ret; | |
329 | } | |
330 | ||
839d52a5 PP |
331 | int bt_event_class_add_field(struct bt_event_class *event_class, |
332 | struct bt_field_type *type, | |
272df73e PP |
333 | const char *name) |
334 | { | |
335 | int ret = 0; | |
336 | ||
f8b979f9 PP |
337 | if (!event_class || !type) { |
338 | BT_LOGW("Invalid parameter: event class or field type is NULL: " | |
339 | "event-class-addr=%p, field-type-addr=%p", | |
340 | event_class, type); | |
341 | ret = -1; | |
342 | goto end; | |
343 | } | |
344 | ||
792defbe | 345 | if (!bt_identifier_is_valid(name)) { |
f8b979f9 PP |
346 | BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: " |
347 | "addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"", | |
839d52a5 PP |
348 | event_class, bt_event_class_get_name(event_class), |
349 | bt_event_class_get_id(event_class), | |
f8b979f9 | 350 | name); |
272df73e PP |
351 | ret = -1; |
352 | goto end; | |
353 | } | |
354 | ||
f8b979f9 PP |
355 | if (event_class->frozen) { |
356 | BT_LOGW("Invalid parameter: event class is frozen: " | |
357 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
358 | event_class, bt_event_class_get_name(event_class), |
359 | bt_event_class_get_id(event_class)); | |
272df73e PP |
360 | ret = -1; |
361 | goto end; | |
362 | } | |
363 | ||
f8b979f9 PP |
364 | if (!event_class->fields) { |
365 | BT_LOGW("Event class has no payload field type: " | |
366 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
367 | event_class, bt_event_class_get_name(event_class), |
368 | bt_event_class_get_id(event_class)); | |
f8b979f9 PP |
369 | ret = -1; |
370 | goto end; | |
371 | } | |
372 | ||
8b45963b | 373 | BT_ASSERT(bt_field_type_get_type_id(event_class->fields) == |
839d52a5 PP |
374 | BT_FIELD_TYPE_ID_STRUCT); |
375 | ret = bt_field_type_structure_add_field(event_class->fields, | |
272df73e | 376 | type, name); |
f8b979f9 PP |
377 | BT_LOGV("Added field to event class's payload field type: " |
378 | "event-class-addr=%p, event-class-name=\"%s\", " | |
379 | "event-class-id=%" PRId64 ", field-name=\"%s\", ft-addr=%p", | |
839d52a5 PP |
380 | event_class, bt_event_class_get_name(event_class), |
381 | bt_event_class_get_id(event_class), name, type); | |
272df73e PP |
382 | end: |
383 | return ret; | |
384 | } | |
385 | ||
839d52a5 PP |
386 | int64_t bt_event_class_get_payload_type_field_count( |
387 | struct bt_event_class *event_class) | |
272df73e | 388 | { |
544d0515 | 389 | int64_t ret; |
272df73e PP |
390 | |
391 | if (!event_class) { | |
f8b979f9 | 392 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
9ac68eb1 | 393 | ret = (int64_t) -1; |
272df73e PP |
394 | goto end; |
395 | } | |
396 | ||
f8b979f9 PP |
397 | if (!event_class->fields) { |
398 | BT_LOGV("Event class has no payload field type: " | |
399 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
400 | event_class, bt_event_class_get_name(event_class), |
401 | bt_event_class_get_id(event_class)); | |
9ac68eb1 | 402 | ret = (int64_t) -1; |
272df73e PP |
403 | goto end; |
404 | } | |
405 | ||
8b45963b | 406 | BT_ASSERT(bt_field_type_get_type_id(event_class->fields) == |
839d52a5 PP |
407 | BT_FIELD_TYPE_ID_STRUCT); |
408 | ret = bt_field_type_structure_get_field_count(event_class->fields); | |
272df73e PP |
409 | end: |
410 | return ret; | |
411 | } | |
412 | ||
839d52a5 PP |
413 | int bt_event_class_get_payload_type_field_by_index( |
414 | struct bt_event_class *event_class, | |
415 | const char **field_name, struct bt_field_type **field_type, | |
9ac68eb1 | 416 | uint64_t index) |
272df73e PP |
417 | { |
418 | int ret; | |
419 | ||
9ac68eb1 | 420 | if (!event_class) { |
f8b979f9 | 421 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
422 | ret = -1; |
423 | goto end; | |
424 | } | |
425 | ||
f8b979f9 PP |
426 | if (!event_class->fields) { |
427 | BT_LOGV("Event class has no payload field type: " | |
428 | "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64, | |
839d52a5 PP |
429 | event_class, bt_event_class_get_name(event_class), |
430 | bt_event_class_get_id(event_class), index); | |
272df73e PP |
431 | ret = -1; |
432 | goto end; | |
433 | } | |
434 | ||
8b45963b | 435 | BT_ASSERT(bt_field_type_get_type_id(event_class->fields) == |
839d52a5 PP |
436 | BT_FIELD_TYPE_ID_STRUCT); |
437 | ret = bt_field_type_structure_get_field_by_index(event_class->fields, | |
272df73e PP |
438 | field_name, field_type, index); |
439 | end: | |
440 | return ret; | |
441 | } | |
442 | ||
839d52a5 PP |
443 | struct bt_field_type * |
444 | bt_event_class_get_payload_type_field_type_by_name( | |
445 | struct bt_event_class *event_class, const char *name) | |
272df73e PP |
446 | { |
447 | GQuark name_quark; | |
839d52a5 | 448 | struct bt_field_type *field_type = NULL; |
272df73e PP |
449 | |
450 | if (!event_class || !name) { | |
32e87ceb | 451 | BT_LOGW("Invalid parameter: event class or name is NULL: " |
f8b979f9 PP |
452 | "event-class-addr=%p, name-addr=%p", |
453 | event_class, name); | |
272df73e PP |
454 | goto end; |
455 | } | |
456 | ||
f8b979f9 PP |
457 | if (!event_class->fields) { |
458 | BT_LOGV("Event class has no payload field type: " | |
459 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
460 | event_class, bt_event_class_get_name(event_class), |
461 | bt_event_class_get_id(event_class)); | |
272df73e PP |
462 | goto end; |
463 | } | |
464 | ||
8b45963b | 465 | BT_ASSERT(bt_field_type_get_type_id(event_class->fields) == |
839d52a5 | 466 | BT_FIELD_TYPE_ID_STRUCT); |
272df73e PP |
467 | name_quark = g_quark_try_string(name); |
468 | if (!name_quark) { | |
f8b979f9 | 469 | BT_LOGE("Cannot get GQuark: string=\"%s\"", name); |
272df73e PP |
470 | goto end; |
471 | } | |
472 | ||
473 | /* | |
474 | * No need to increment field_type's reference count since getting it | |
475 | * from the structure already does. | |
476 | */ | |
839d52a5 | 477 | field_type = bt_field_type_structure_get_field_type_by_name( |
272df73e PP |
478 | event_class->fields, name); |
479 | end: | |
480 | return field_type; | |
481 | } | |
482 | ||
839d52a5 PP |
483 | struct bt_field_type *bt_event_class_get_context_type( |
484 | struct bt_event_class *event_class) | |
272df73e | 485 | { |
839d52a5 | 486 | struct bt_field_type *context_type = NULL; |
272df73e | 487 | |
44ea72c5 | 488 | BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); |
f8b979f9 PP |
489 | |
490 | if (!event_class->context) { | |
491 | BT_LOGV("Event class has no context field type: " | |
492 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
493 | event_class, bt_event_class_get_name(event_class), |
494 | bt_event_class_get_id(event_class)); | |
272df73e PP |
495 | goto end; |
496 | } | |
497 | ||
44ea72c5 PP |
498 | context_type = bt_get(event_class->context); |
499 | ||
272df73e PP |
500 | end: |
501 | return context_type; | |
502 | } | |
503 | ||
839d52a5 PP |
504 | int bt_event_class_set_context_type( |
505 | struct bt_event_class *event_class, | |
506 | struct bt_field_type *context) | |
272df73e PP |
507 | { |
508 | int ret = 0; | |
509 | ||
f8b979f9 PP |
510 | if (!event_class) { |
511 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
512 | ret = -1; | |
513 | goto end; | |
514 | } | |
515 | ||
516 | if (event_class->frozen) { | |
517 | BT_LOGW("Invalid parameter: event class is frozen: " | |
518 | "addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
519 | event_class, bt_event_class_get_name(event_class), |
520 | bt_event_class_get_id(event_class)); | |
272df73e PP |
521 | ret = -1; |
522 | goto end; | |
523 | } | |
524 | ||
839d52a5 PP |
525 | if (context && bt_field_type_get_type_id(context) != |
526 | BT_FIELD_TYPE_ID_STRUCT) { | |
f8b979f9 PP |
527 | BT_LOGW("Invalid parameter: event class's context field type must be a structure: " |
528 | "addr=%p, name=\"%s\", id=%" PRId64 ", " | |
529 | "context-ft-id=%s", | |
839d52a5 PP |
530 | event_class, bt_event_class_get_name(event_class), |
531 | bt_event_class_get_id(event_class), | |
532 | bt_field_type_id_string( | |
533 | bt_field_type_get_type_id(context))); | |
272df73e PP |
534 | ret = -1; |
535 | goto end; | |
536 | } | |
537 | ||
272df73e | 538 | bt_put(event_class->context); |
835b2d10 | 539 | event_class->context = bt_get(context); |
f8b979f9 PP |
540 | BT_LOGV("Set event class's context field type: " |
541 | "event-class-addr=%p, event-class-name=\"%s\", " | |
542 | "event-class-id=%" PRId64 ", context-ft-addr=%p", | |
839d52a5 PP |
543 | event_class, bt_event_class_get_name(event_class), |
544 | bt_event_class_get_id(event_class), context); | |
272df73e PP |
545 | end: |
546 | return ret; | |
547 | ||
548 | } | |
549 | ||
f8b979f9 | 550 | /* Pre-2.0 CTF writer backward compatibility */ |
839d52a5 | 551 | void bt_ctf_event_class_get(struct bt_event_class *event_class) |
272df73e PP |
552 | { |
553 | bt_get(event_class); | |
554 | } | |
555 | ||
f8b979f9 | 556 | /* Pre-2.0 CTF writer backward compatibility */ |
839d52a5 | 557 | void bt_ctf_event_class_put(struct bt_event_class *event_class) |
272df73e PP |
558 | { |
559 | bt_put(event_class); | |
560 | } | |
561 | ||
272df73e | 562 | static |
839d52a5 | 563 | void bt_event_class_destroy(struct bt_object *obj) |
272df73e | 564 | { |
839d52a5 | 565 | struct bt_event_class *event_class; |
272df73e | 566 | |
839d52a5 | 567 | event_class = container_of(obj, struct bt_event_class, base); |
f8b979f9 | 568 | BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64, |
839d52a5 PP |
569 | event_class, bt_event_class_get_name(event_class), |
570 | bt_event_class_get_id(event_class)); | |
9cf5d083 PP |
571 | g_string_free(event_class->name, TRUE); |
572 | g_string_free(event_class->emf_uri, TRUE); | |
03409974 | 573 | BT_LOGD_STR("Putting context field type."); |
272df73e | 574 | bt_put(event_class->context); |
03409974 | 575 | BT_LOGD_STR("Putting payload field type."); |
272df73e PP |
576 | bt_put(event_class->fields); |
577 | g_free(event_class); | |
578 | } | |
579 | ||
580 | BT_HIDDEN | |
839d52a5 | 581 | void bt_event_class_freeze(struct bt_event_class *event_class) |
272df73e | 582 | { |
8b45963b | 583 | BT_ASSERT(event_class); |
f8b979f9 PP |
584 | |
585 | if (event_class->frozen) { | |
586 | return; | |
587 | } | |
588 | ||
589 | BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64, | |
839d52a5 PP |
590 | event_class, bt_event_class_get_name(event_class), |
591 | bt_event_class_get_id(event_class)); | |
272df73e | 592 | event_class->frozen = 1; |
0352f8fa | 593 | BT_LOGD_STR("Freezing event class's context field type."); |
839d52a5 | 594 | bt_field_type_freeze(event_class->context); |
0352f8fa | 595 | BT_LOGD_STR("Freezing event class's payload field type."); |
839d52a5 | 596 | bt_field_type_freeze(event_class->fields); |
272df73e PP |
597 | } |
598 | ||
599 | BT_HIDDEN | |
839d52a5 | 600 | int bt_event_class_serialize(struct bt_event_class *event_class, |
272df73e PP |
601 | struct metadata_context *context) |
602 | { | |
272df73e PP |
603 | int ret = 0; |
604 | struct bt_value *attr_value = NULL; | |
605 | ||
8b45963b PP |
606 | BT_ASSERT(event_class); |
607 | BT_ASSERT(context); | |
f8b979f9 PP |
608 | BT_LOGD("Serializing event class's metadata: " |
609 | "event-class-addr=%p, event-class-name=\"%s\", " | |
610 | "event-class-id=%" PRId64 ", metadata-context-addr=%p", | |
839d52a5 PP |
611 | event_class, bt_event_class_get_name(event_class), |
612 | bt_event_class_get_id(event_class), context); | |
272df73e PP |
613 | context->current_indentation_level = 1; |
614 | g_string_assign(context->field_name, ""); | |
615 | g_string_append(context->string, "event {\n"); | |
272df73e | 616 | |
9cf5d083 PP |
617 | /* Serialize attributes */ |
618 | g_string_append_printf(context->string, "\tname = \"%s\";\n", | |
619 | event_class->name->str); | |
8b45963b | 620 | BT_ASSERT(event_class->id >= 0); |
9cf5d083 PP |
621 | g_string_append_printf(context->string, "\tid = %" PRId64 ";\n", |
622 | event_class->id); | |
623 | g_string_append_printf(context->string, "\tstream_id = %" PRId64 ";\n", | |
839d52a5 PP |
624 | bt_stream_class_get_id( |
625 | bt_event_class_borrow_stream_class(event_class))); | |
272df73e | 626 | |
839d52a5 | 627 | if (event_class->log_level != BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) { |
9cf5d083 PP |
628 | g_string_append_printf(context->string, "\tloglevel = %d;\n", |
629 | (int) event_class->log_level); | |
630 | } | |
272df73e | 631 | |
9cf5d083 PP |
632 | if (event_class->emf_uri->len > 0) { |
633 | g_string_append_printf(context->string, "\tmodel.emf.uri = \"%s\";\n", | |
634 | event_class->emf_uri->str); | |
272df73e PP |
635 | } |
636 | ||
9cf5d083 | 637 | /* Serialize context field type */ |
272df73e PP |
638 | if (event_class->context) { |
639 | g_string_append(context->string, "\tcontext := "); | |
0352f8fa | 640 | BT_LOGD_STR("Serializing event class's context field type metadata."); |
839d52a5 | 641 | ret = bt_field_type_serialize(event_class->context, |
272df73e PP |
642 | context); |
643 | if (ret) { | |
66871d36 | 644 | BT_LOGW("Cannot serialize event class's context field type's metadata: " |
f8b979f9 | 645 | "ret=%d", ret); |
272df73e PP |
646 | goto end; |
647 | } | |
648 | g_string_append(context->string, ";\n"); | |
649 | } | |
650 | ||
9cf5d083 | 651 | /* Serialize payload field type */ |
272df73e PP |
652 | if (event_class->fields) { |
653 | g_string_append(context->string, "\tfields := "); | |
0352f8fa | 654 | BT_LOGD_STR("Serializing event class's payload field type metadata."); |
839d52a5 | 655 | ret = bt_field_type_serialize(event_class->fields, context); |
272df73e | 656 | if (ret) { |
66871d36 | 657 | BT_LOGW("Cannot serialize event class's payload field type's metadata: " |
f8b979f9 | 658 | "ret=%d", ret); |
272df73e PP |
659 | goto end; |
660 | } | |
661 | g_string_append(context->string, ";\n"); | |
662 | } | |
663 | ||
664 | g_string_append(context->string, "};\n\n"); | |
665 | end: | |
666 | context->current_indentation_level = 0; | |
667 | BT_PUT(attr_value); | |
668 | return ret; | |
669 | } | |
8c4a29ba PP |
670 | |
671 | BT_HIDDEN | |
672 | int bt_event_class_validate_single_clock_class( | |
673 | struct bt_event_class *event_class, | |
674 | struct bt_clock_class **expected_clock_class) | |
675 | { | |
676 | int ret = 0; | |
677 | ||
8b45963b PP |
678 | BT_ASSERT(event_class); |
679 | BT_ASSERT(expected_clock_class); | |
8c4a29ba PP |
680 | ret = bt_validate_single_clock_class(event_class->context, |
681 | expected_clock_class); | |
682 | if (ret) { | |
683 | BT_LOGW("Event class's context field type " | |
684 | "is not recursively mapped to the " | |
685 | "expected clock class: " | |
686 | "event-class-addr=%p, " | |
687 | "event-class-name=\"%s\", " | |
688 | "event-class-id=%" PRId64 ", " | |
689 | "ft-addr=%p", | |
690 | event_class, | |
691 | bt_event_class_get_name(event_class), | |
692 | event_class->id, | |
693 | event_class->context); | |
694 | goto end; | |
695 | } | |
696 | ||
697 | ret = bt_validate_single_clock_class(event_class->fields, | |
698 | expected_clock_class); | |
699 | if (ret) { | |
700 | BT_LOGW("Event class's payload field type " | |
701 | "is not recursively mapped to the " | |
702 | "expected clock class: " | |
703 | "event-class-addr=%p, " | |
704 | "event-class-name=\"%s\", " | |
705 | "event-class-id=%" PRId64 ", " | |
706 | "ft-addr=%p", | |
707 | event_class, | |
708 | bt_event_class_get_name(event_class), | |
709 | event_class->id, | |
710 | event_class->fields); | |
711 | goto end; | |
712 | } | |
713 | ||
714 | end: | |
715 | return ret; | |
716 | } |