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