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