Fix : coherency in const parameters
[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 /*
33 * thread local storage to store the last error that occured
34 * while reading a field, this variable must be accessed by
35 * bt_ctf_field_error only
36 */
37 __thread int bt_ctf_last_field_error = 0;
38
39 struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx,
40 struct bt_iter_pos *begin_pos,
41 struct bt_iter_pos *end_pos)
42 {
43 struct bt_ctf_iter *iter;
44 int ret;
45
46 iter = g_new0(struct bt_ctf_iter, 1);
47 ret = bt_iter_init(&iter->parent, ctx, begin_pos, end_pos);
48 if (ret) {
49 g_free(iter);
50 return NULL;
51 }
52 iter->callbacks = g_array_new(0, 1, sizeof(struct bt_stream_callbacks));
53 iter->recalculate_dep_graph = 0;
54 iter->main_callbacks.callback = NULL;
55 iter->dep_gc = g_ptr_array_new();
56 return iter;
57 }
58
59 void bt_ctf_iter_destroy(struct bt_ctf_iter *iter)
60 {
61 struct bt_stream_callbacks *bt_stream_cb;
62 struct bt_callback_chain *bt_chain;
63 int i, j;
64
65 /* free all events callbacks */
66 if (iter->main_callbacks.callback)
67 g_array_free(iter->main_callbacks.callback, TRUE);
68
69 /* free per-event callbacks */
70 for (i = 0; i < iter->callbacks->len; i++) {
71 bt_stream_cb = &g_array_index(iter->callbacks,
72 struct bt_stream_callbacks, i);
73 if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks)
74 continue;
75 for (j = 0; j < bt_stream_cb->per_id_callbacks->len; j++) {
76 bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
77 struct bt_callback_chain, j);
78 if (bt_chain->callback) {
79 g_array_free(bt_chain->callback, TRUE);
80 }
81 }
82 g_array_free(bt_stream_cb->per_id_callbacks, TRUE);
83 }
84
85 bt_iter_fini(&iter->parent);
86 g_free(iter);
87 }
88
89 struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter)
90 {
91 return &iter->parent;
92 }
93
94 struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter)
95 {
96 struct ctf_file_stream *file_stream;
97 struct bt_ctf_event *ret = &iter->current_ctf_event;
98
99 file_stream = heap_maximum(iter->parent.stream_heap);
100 if (!file_stream) {
101 /* end of file for all streams */
102 goto stop;
103 }
104 ret->stream = &file_stream->parent;
105 ret->event = g_ptr_array_index(ret->stream->events_by_id,
106 ret->stream->event_id);
107
108 if (ret->stream->stream_id > iter->callbacks->len)
109 goto end;
110
111 process_callbacks(iter, ret->stream);
112
113 end:
114 return ret;
115 stop:
116 return NULL;
117 }
118
119 struct definition *bt_ctf_get_top_level_scope(struct bt_ctf_event *event,
120 enum bt_ctf_scope scope)
121 {
122 struct definition *tmp = NULL;
123
124 switch (scope) {
125 case BT_TRACE_PACKET_HEADER:
126 if (!event->stream)
127 goto error;
128 if (event->stream->trace_packet_header)
129 tmp = &event->stream->trace_packet_header->p;
130 break;
131 case BT_STREAM_PACKET_CONTEXT:
132 if (!event->stream)
133 goto error;
134 if (event->stream->stream_packet_context)
135 tmp = &event->stream->stream_packet_context->p;
136 break;
137 case BT_STREAM_EVENT_HEADER:
138 if (!event->stream)
139 goto error;
140 if (event->stream->stream_event_header)
141 tmp = &event->stream->stream_event_header->p;
142 break;
143 case BT_STREAM_EVENT_CONTEXT:
144 if (!event->stream)
145 goto error;
146 if (event->stream->stream_event_context)
147 tmp = &event->stream->stream_event_context->p;
148 break;
149 case BT_EVENT_CONTEXT:
150 if (!event->event)
151 goto error;
152 if (event->event->event_context)
153 tmp = &event->event->event_context->p;
154 break;
155 case BT_EVENT_FIELDS:
156 if (!event->event)
157 goto error;
158 if (event->event->event_fields)
159 tmp = &event->event->event_fields->p;
160 break;
161 }
162 return tmp;
163
164 error:
165 return NULL;
166 }
167
168 struct definition *bt_ctf_get_field(struct bt_ctf_event *event,
169 struct definition *scope,
170 const char *field)
171 {
172 struct definition *def;
173
174 if (scope) {
175 def = lookup_definition(scope, field);
176 if (bt_ctf_field_type(def) == CTF_TYPE_VARIANT) {
177 struct definition_variant *variant_definition;
178 variant_definition = container_of(def,
179 struct definition_variant, p);
180 return variant_definition->current_field;
181 }
182 return def;
183 }
184 return NULL;
185 }
186
187 struct definition *bt_ctf_get_index(struct bt_ctf_event *event,
188 struct definition *field,
189 unsigned int index)
190 {
191 struct definition *ret = NULL;
192
193 if (bt_ctf_field_type(field) == CTF_TYPE_ARRAY) {
194 struct definition_array *array_definition;
195 array_definition = container_of(field,
196 struct definition_array, p);
197 ret = array_index(array_definition, index);
198 } else if (bt_ctf_field_type(field) == CTF_TYPE_SEQUENCE) {
199 struct definition_sequence *sequence_definition;
200 sequence_definition = container_of(field,
201 struct definition_sequence, p);
202 ret = sequence_index(sequence_definition, index);
203 }
204 return ret;
205 }
206
207 const char *bt_ctf_event_name(struct bt_ctf_event *event)
208 {
209 struct ctf_event *event_class;
210 struct ctf_stream_class *stream_class;
211
212 if (!event)
213 return NULL;
214 stream_class = event->stream->stream_class;
215 event_class = g_ptr_array_index(stream_class->events_by_id,
216 event->stream->event_id);
217 return g_quark_to_string(event_class->name);
218 }
219
220 const char *bt_ctf_field_name(const struct definition *def)
221 {
222 if (def)
223 return g_quark_to_string(def->name);
224 return NULL;
225 }
226
227 enum ctf_type_id bt_ctf_field_type(const struct definition *def)
228 {
229 if (def)
230 return def->declaration->id;
231 return CTF_TYPE_UNKNOWN;
232 }
233
234 int bt_ctf_get_field_list(struct bt_ctf_event *event,
235 struct definition *scope,
236 struct definition const * const **list,
237 unsigned int *count)
238 {
239 switch (bt_ctf_field_type(scope)) {
240 case CTF_TYPE_INTEGER:
241 case CTF_TYPE_FLOAT:
242 case CTF_TYPE_STRING:
243 case CTF_TYPE_ENUM:
244 goto error;
245 case CTF_TYPE_STRUCT:
246 {
247 struct definition_struct *def_struct;
248
249 def_struct = container_of(scope, struct definition_struct, p);
250 if (!def_struct)
251 goto error;
252 if (def_struct->fields->pdata) {
253 *list = (struct definition const* const*) def_struct->fields->pdata;
254 *count = def_struct->fields->len;
255 goto end;
256 } else {
257 goto error;
258 }
259 }
260 case CTF_TYPE_UNTAGGED_VARIANT:
261 goto error;
262 case CTF_TYPE_VARIANT:
263 {
264 struct definition_variant *def_variant;
265
266 def_variant = container_of(scope, struct definition_variant, p);
267 if (!def_variant)
268 goto error;
269 if (def_variant->fields->pdata) {
270 *list = (struct definition const* const*) def_variant->fields->pdata;
271 *count = def_variant->fields->len;
272 goto end;
273 } else {
274 goto error;
275 }
276 }
277 case CTF_TYPE_ARRAY:
278 {
279 struct definition_array *def_array;
280
281 def_array = container_of(scope, struct definition_array, p);
282 if (!def_array)
283 goto error;
284 if (def_array->elems->pdata) {
285 *list = (struct definition const* const*) def_array->elems->pdata;
286 *count = def_array->elems->len;
287 goto end;
288 } else {
289 goto error;
290 }
291 }
292 case CTF_TYPE_SEQUENCE:
293 {
294 struct definition_sequence *def_sequence;
295
296 def_sequence = container_of(scope, struct definition_sequence, p);
297 if (!def_sequence)
298 goto error;
299 if (def_sequence->elems->pdata) {
300 *list = (struct definition const* const*) def_sequence->elems->pdata;
301 *count = def_sequence->elems->len;
302 goto end;
303 } else {
304 goto error;
305 }
306 }
307 default:
308 break;
309 }
310
311 end:
312 return 0;
313
314 error:
315 *list = NULL;
316 *count = 0;
317 return -1;
318 }
319
320 uint64_t bt_ctf_get_timestamp(struct bt_ctf_event *event)
321 {
322 if (event && event->stream->has_timestamp)
323 return event->stream->timestamp;
324 else
325 return 0;
326 }
327
328 static void bt_ctf_field_set_error(int error)
329 {
330 bt_ctf_last_field_error = error;
331 }
332
333 int bt_ctf_field_get_error(void)
334 {
335 int ret;
336 ret = bt_ctf_last_field_error;
337 bt_ctf_last_field_error = 0;
338
339 return ret;
340 }
341
342 uint64_t bt_ctf_get_uint64(const struct definition *field)
343 {
344 unsigned int ret = 0;
345
346 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
347 ret = get_unsigned_int(field);
348 else
349 bt_ctf_field_set_error(-EINVAL);
350
351 return ret;
352 }
353
354 int64_t bt_ctf_get_int64(const struct definition *field)
355 {
356 int ret = 0;
357
358 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
359 ret = get_signed_int(field);
360 else
361 bt_ctf_field_set_error(-EINVAL);
362
363 return ret;
364
365 }
366
367 char *bt_ctf_get_char_array(const struct definition *field)
368 {
369 char *ret = NULL;
370
371 if (field && bt_ctf_field_type(field) == CTF_TYPE_ARRAY)
372 ret = get_char_array(field)->str;
373 else
374 bt_ctf_field_set_error(-EINVAL);
375
376 return ret;
377 }
378
379 char *bt_ctf_get_string(const struct definition *field)
380 {
381 char *ret = NULL;
382
383 if (field && bt_ctf_field_type(field) == CTF_TYPE_STRING)
384 ret = get_string(field);
385 else
386 bt_ctf_field_set_error(-EINVAL);
387
388 return ret;
389 }
This page took 0.037075 seconds and 5 git commands to generate.