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