Fix API : functions to access fields properties
[babeltrace.git] / formats / ctf / events.c
1 /*
2 * ctf/events.c
3 *
4 * Babeltrace Library
5 *
6 * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
7 *
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Julien Desfossez <julien.desfossez@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 */
21
22 #include <babeltrace/babeltrace.h>
23 #include <babeltrace/format.h>
24 #include <babeltrace/ctf/events.h>
25 #include <babeltrace/ctf-ir/metadata.h>
26 #include <babeltrace/prio_heap.h>
27 #include <babeltrace/iterator-internal.h>
28 #include <babeltrace/ctf/events-internal.h>
29 #include <babeltrace/ctf/metadata.h>
30 #include <glib.h>
31
32 #include "events-private.h"
33
34 /*
35 * thread local storage to store the last error that occured
36 * while reading a field, this variable must be accessed by
37 * bt_ctf_field_error only
38 */
39 __thread int bt_ctf_last_field_error = 0;
40
41 struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx,
42 struct bt_iter_pos *begin_pos,
43 struct bt_iter_pos *end_pos)
44 {
45 struct bt_ctf_iter *iter;
46 int ret;
47
48 iter = g_new0(struct bt_ctf_iter, 1);
49 ret = bt_iter_init(&iter->parent, ctx, begin_pos, end_pos);
50 if (ret) {
51 g_free(iter);
52 return NULL;
53 }
54 iter->callbacks = g_array_new(0, 1, sizeof(struct bt_stream_callbacks));
55 iter->recalculate_dep_graph = 0;
56 iter->main_callbacks.callback = NULL;
57 iter->dep_gc = g_ptr_array_new();
58 return iter;
59 }
60
61 void bt_ctf_iter_destroy(struct bt_ctf_iter *iter)
62 {
63 struct bt_stream_callbacks *bt_stream_cb;
64 struct bt_callback_chain *bt_chain;
65 int i, j;
66
67 /* free all events callbacks */
68 if (iter->main_callbacks.callback)
69 g_array_free(iter->main_callbacks.callback, TRUE);
70
71 /* free per-event callbacks */
72 for (i = 0; i < iter->callbacks->len; i++) {
73 bt_stream_cb = &g_array_index(iter->callbacks,
74 struct bt_stream_callbacks, i);
75 if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks)
76 continue;
77 for (j = 0; j < bt_stream_cb->per_id_callbacks->len; j++) {
78 bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
79 struct bt_callback_chain, j);
80 if (bt_chain->callback) {
81 g_array_free(bt_chain->callback, TRUE);
82 }
83 }
84 g_array_free(bt_stream_cb->per_id_callbacks, TRUE);
85 }
86
87 bt_iter_fini(&iter->parent);
88 g_free(iter);
89 }
90
91 struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter)
92 {
93 return &iter->parent;
94 }
95
96 struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter)
97 {
98 struct ctf_file_stream *file_stream;
99 struct bt_ctf_event *ret = &iter->current_ctf_event;
100
101 file_stream = heap_maximum(iter->parent.stream_heap);
102 if (!file_stream) {
103 /* end of file for all streams */
104 goto stop;
105 }
106 ret->stream = &file_stream->parent;
107 ret->event = g_ptr_array_index(ret->stream->events_by_id,
108 ret->stream->event_id);
109
110 if (ret->stream->stream_id > iter->callbacks->len)
111 goto end;
112
113 process_callbacks(iter, ret->stream);
114
115 end:
116 return ret;
117 stop:
118 return NULL;
119 }
120
121 struct definition *bt_ctf_get_top_level_scope(struct bt_ctf_event *event,
122 enum bt_ctf_scope scope)
123 {
124 struct definition *tmp = NULL;
125
126 switch (scope) {
127 case BT_TRACE_PACKET_HEADER:
128 if (!event->stream)
129 goto error;
130 if (event->stream->trace_packet_header)
131 tmp = &event->stream->trace_packet_header->p;
132 break;
133 case BT_STREAM_PACKET_CONTEXT:
134 if (!event->stream)
135 goto error;
136 if (event->stream->stream_packet_context)
137 tmp = &event->stream->stream_packet_context->p;
138 break;
139 case BT_STREAM_EVENT_HEADER:
140 if (!event->stream)
141 goto error;
142 if (event->stream->stream_event_header)
143 tmp = &event->stream->stream_event_header->p;
144 break;
145 case BT_STREAM_EVENT_CONTEXT:
146 if (!event->stream)
147 goto error;
148 if (event->stream->stream_event_context)
149 tmp = &event->stream->stream_event_context->p;
150 break;
151 case BT_EVENT_CONTEXT:
152 if (!event->event)
153 goto error;
154 if (event->event->event_context)
155 tmp = &event->event->event_context->p;
156 break;
157 case BT_EVENT_FIELDS:
158 if (!event->event)
159 goto error;
160 if (event->event->event_fields)
161 tmp = &event->event->event_fields->p;
162 break;
163 }
164 return tmp;
165
166 error:
167 return NULL;
168 }
169
170 struct definition *bt_ctf_get_field(struct bt_ctf_event *event,
171 struct definition *scope,
172 const char *field)
173 {
174 struct definition *def;
175
176 if (scope) {
177 def = lookup_definition(scope, field);
178 if (bt_ctf_field_type(def) == CTF_TYPE_VARIANT) {
179 struct definition_variant *variant_definition;
180 variant_definition = container_of(def,
181 struct definition_variant, p);
182 return variant_definition->current_field;
183 }
184 return def;
185 }
186 return NULL;
187 }
188
189 struct definition *bt_ctf_get_index(struct bt_ctf_event *event,
190 struct definition *field,
191 unsigned int index)
192 {
193 struct definition *ret = NULL;
194
195 if (bt_ctf_field_type(field) == CTF_TYPE_ARRAY) {
196 struct definition_array *array_definition;
197 array_definition = container_of(field,
198 struct definition_array, p);
199 ret = array_index(array_definition, index);
200 } else if (bt_ctf_field_type(field) == CTF_TYPE_SEQUENCE) {
201 struct definition_sequence *sequence_definition;
202 sequence_definition = container_of(field,
203 struct definition_sequence, p);
204 ret = sequence_index(sequence_definition, index);
205 }
206 return ret;
207 }
208
209 const char *bt_ctf_event_name(struct bt_ctf_event *event)
210 {
211 struct ctf_event *event_class;
212 struct ctf_stream_class *stream_class;
213
214 if (!event)
215 return NULL;
216 stream_class = event->stream->stream_class;
217 event_class = g_ptr_array_index(stream_class->events_by_id,
218 event->stream->event_id);
219 return g_quark_to_string(event_class->name);
220 }
221
222 const char *bt_ctf_field_name(const struct definition *def)
223 {
224 if (def)
225 return g_quark_to_string(def->name);
226 return NULL;
227 }
228
229 enum ctf_type_id bt_ctf_field_type(const struct definition *def)
230 {
231 if (def)
232 return def->declaration->id;
233 return CTF_TYPE_UNKNOWN;
234 }
235
236 int bt_ctf_get_field_list(struct bt_ctf_event *event,
237 struct definition *scope,
238 struct definition const * const **list,
239 unsigned int *count)
240 {
241 switch (bt_ctf_field_type(scope)) {
242 case CTF_TYPE_INTEGER:
243 case CTF_TYPE_FLOAT:
244 case CTF_TYPE_STRING:
245 case CTF_TYPE_ENUM:
246 goto error;
247 case CTF_TYPE_STRUCT:
248 {
249 struct definition_struct *def_struct;
250
251 def_struct = container_of(scope, struct definition_struct, p);
252 if (!def_struct)
253 goto error;
254 if (def_struct->fields->pdata) {
255 *list = (struct definition const* const*) def_struct->fields->pdata;
256 *count = def_struct->fields->len;
257 goto end;
258 } else {
259 goto error;
260 }
261 }
262 case CTF_TYPE_UNTAGGED_VARIANT:
263 goto error;
264 case CTF_TYPE_VARIANT:
265 {
266 struct definition_variant *def_variant;
267
268 def_variant = container_of(scope, struct definition_variant, p);
269 if (!def_variant)
270 goto error;
271 if (def_variant->fields->pdata) {
272 *list = (struct definition const* const*) def_variant->fields->pdata;
273 *count = def_variant->fields->len;
274 goto end;
275 } else {
276 goto error;
277 }
278 }
279 case CTF_TYPE_ARRAY:
280 {
281 struct definition_array *def_array;
282
283 def_array = container_of(scope, struct definition_array, p);
284 if (!def_array)
285 goto error;
286 if (def_array->elems->pdata) {
287 *list = (struct definition const* const*) def_array->elems->pdata;
288 *count = def_array->elems->len;
289 goto end;
290 } else {
291 goto error;
292 }
293 }
294 case CTF_TYPE_SEQUENCE:
295 {
296 struct definition_sequence *def_sequence;
297
298 def_sequence = container_of(scope, struct definition_sequence, p);
299 if (!def_sequence)
300 goto error;
301 if (def_sequence->elems->pdata) {
302 *list = (struct definition const* const*) def_sequence->elems->pdata;
303 *count = def_sequence->elems->len;
304 goto end;
305 } else {
306 goto error;
307 }
308 }
309 default:
310 break;
311 }
312
313 end:
314 return 0;
315
316 error:
317 *list = NULL;
318 *count = 0;
319 return -1;
320 }
321
322 uint64_t bt_ctf_get_timestamp_raw(struct bt_ctf_event *event)
323 {
324 if (event && event->stream->has_timestamp)
325 return ctf_get_timestamp_raw(event->stream,
326 event->stream->timestamp);
327 else
328 return -1ULL;
329 }
330
331 uint64_t bt_ctf_get_timestamp(struct bt_ctf_event *event)
332 {
333 if (event && event->stream->has_timestamp)
334 return ctf_get_timestamp(event->stream,
335 event->stream->timestamp);
336 else
337 return -1ULL;
338 }
339
340 static void bt_ctf_field_set_error(int error)
341 {
342 bt_ctf_last_field_error = error;
343 }
344
345 int bt_ctf_field_get_error(void)
346 {
347 int ret;
348 ret = bt_ctf_last_field_error;
349 bt_ctf_last_field_error = 0;
350
351 return ret;
352 }
353
354 int bt_ctf_get_int_signedness(const struct definition *field)
355 {
356 int ret;
357
358 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER) {
359 ret = get_int_signedness(field);
360 } else {
361 ret = -1;
362 bt_ctf_field_set_error(-EINVAL);
363 }
364
365 return ret;
366 }
367
368 int bt_ctf_get_int_base(const struct definition *field)
369 {
370 int ret;
371
372 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER) {
373 ret = get_int_base(field);
374 } else {
375 ret = -1;
376 bt_ctf_field_set_error(-EINVAL);
377 }
378
379 return ret;
380 }
381
382 int bt_ctf_get_int_byte_order(const struct definition *field)
383 {
384 int ret;
385
386 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER) {
387 ret = get_int_byte_order(field);
388 } else {
389 ret = -1;
390 bt_ctf_field_set_error(-EINVAL);
391 }
392
393 return ret;
394 }
395
396 enum ctf_string_encoding bt_ctf_get_encoding(const struct definition *field)
397 {
398 enum ctf_string_encoding ret = 0;
399
400 if (!field)
401 goto end;
402
403 if (bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
404 ret = get_int_encoding(field);
405 else if (bt_ctf_field_type(field) == CTF_TYPE_STRING)
406 ret = get_string_encoding(field);
407 else
408 goto error;
409
410 end:
411 return ret;
412
413 error:
414 bt_ctf_field_set_error(-EINVAL);
415 return -1;
416 }
417
418 int bt_ctf_get_array_len(const struct definition *field)
419 {
420 int ret;
421
422 if (field && bt_ctf_field_type(field) == CTF_TYPE_ARRAY) {
423 ret = get_array_len(field);
424 } else {
425 ret = -1;
426 bt_ctf_field_set_error(-EINVAL);
427 }
428
429 return ret;
430 }
431
432 uint64_t bt_ctf_get_uint64(const struct definition *field)
433 {
434 unsigned int ret = 0;
435
436 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
437 ret = get_unsigned_int(field);
438 else
439 bt_ctf_field_set_error(-EINVAL);
440
441 return ret;
442 }
443
444 int64_t bt_ctf_get_int64(const struct definition *field)
445 {
446 int ret = 0;
447
448 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
449 ret = get_signed_int(field);
450 else
451 bt_ctf_field_set_error(-EINVAL);
452
453 return ret;
454
455 }
456
457 char *bt_ctf_get_char_array(const struct definition *field)
458 {
459 char *ret = NULL;
460
461 if (field && bt_ctf_field_type(field) == CTF_TYPE_ARRAY)
462 ret = get_char_array(field)->str;
463 else
464 bt_ctf_field_set_error(-EINVAL);
465
466 return ret;
467 }
468
469 char *bt_ctf_get_string(const struct definition *field)
470 {
471 char *ret = NULL;
472
473 if (field && bt_ctf_field_type(field) == CTF_TYPE_STRING)
474 ret = get_string(field);
475 else
476 bt_ctf_field_set_error(-EINVAL);
477
478 return ret;
479 }
This page took 0.040527 seconds and 5 git commands to generate.