API : Access CTF events fields
[babeltrace.git] / lib / ctf-events.c
CommitLineData
9843982d
JD
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 <glib.h>
27
28/*
29 * thread local storage to store the last error that occured
30 * while reading a field, this variable must be accessed by
31 * bt_ctf_field_error only
32 */
33__thread int bt_ctf_last_field_error = 0;
34
35struct definition *bt_ctf_get_top_level_scope(struct bt_ctf_event *event,
36 enum bt_ctf_scope scope)
37{
38 struct definition *tmp = NULL;
39
40 switch (scope) {
41 case BT_TRACE_PACKET_HEADER:
42 if (!event->stream)
43 goto error;
44 if (event->stream->trace_packet_header)
45 tmp = &event->stream->trace_packet_header->p;
46 break;
47 case BT_STREAM_PACKET_CONTEXT:
48 if (!event->stream)
49 goto error;
50 if (event->stream->stream_packet_context)
51 tmp = &event->stream->stream_packet_context->p;
52 break;
53 case BT_STREAM_EVENT_HEADER:
54 if (!event->stream)
55 goto error;
56 if (event->stream->stream_event_header)
57 tmp = &event->stream->stream_event_header->p;
58 break;
59 case BT_STREAM_EVENT_CONTEXT:
60 if (!event->stream)
61 goto error;
62 if (event->stream->stream_event_context)
63 tmp = &event->stream->stream_event_context->p;
64 break;
65 case BT_EVENT_CONTEXT:
66 if (!event->event)
67 goto error;
68 if (event->event->event_context)
69 tmp = &event->event->event_context->p;
70 break;
71 case BT_EVENT_FIELDS:
72 if (!event->event)
73 goto error;
74 if (event->event->event_fields)
75 tmp = &event->event->event_fields->p;
76 break;
77 }
78 return tmp;
79
80error:
81 return NULL;
82}
83
84struct definition *bt_ctf_get_field(struct bt_ctf_event *event,
85 struct definition *scope,
86 const char *field)
87{
88 struct definition *def;
89
90 if (scope) {
91 def = lookup_definition(scope, field);
92 if (bt_ctf_field_type(def) == CTF_TYPE_VARIANT) {
93 struct definition_variant *variant_definition;
94 variant_definition = container_of(def,
95 struct definition_variant, p);
96 return variant_definition->current_field;
97 }
98 return def;
99 }
100 return NULL;
101}
102
103struct definition *bt_ctf_get_index(struct bt_ctf_event *event,
104 struct definition *field,
105 unsigned int index)
106{
107 struct definition *ret = NULL;
108
109 if (bt_ctf_field_type(field) == CTF_TYPE_ARRAY) {
110 struct definition_array *array_definition;
111 array_definition = container_of(field,
112 struct definition_array, p);
113 ret = array_index(array_definition, index);
114 } else if (bt_ctf_field_type(field) == CTF_TYPE_SEQUENCE) {
115 struct definition_sequence *sequence_definition;
116 sequence_definition = container_of(field,
117 struct definition_sequence, p);
118 ret = sequence_index(sequence_definition, index);
119 }
120 return ret;
121}
122
123const char *bt_ctf_event_name(struct bt_ctf_event *event)
124{
125 struct ctf_event *event_class;
126 struct ctf_stream_class *stream_class;
127
128 if (!event)
129 return NULL;
130 stream_class = event->stream->stream_class;
131 event_class = g_ptr_array_index(stream_class->events_by_id,
132 event->stream->event_id);
133 return g_quark_to_string(event_class->name);
134}
135
136const char *bt_ctf_field_name(const struct definition *def)
137{
138 if (def)
139 return g_quark_to_string(def->name);
140 return NULL;
141}
142
143enum ctf_type_id bt_ctf_field_type(struct definition *def)
144{
145 if (def)
146 return def->declaration->id;
147 return CTF_TYPE_UNKNOWN;
148}
149
150int bt_ctf_get_field_list(struct bt_ctf_event *event,
151 struct definition *scope,
152 struct definition const * const **list,
153 unsigned int *count)
154{
155 switch (bt_ctf_field_type(scope)) {
156 case CTF_TYPE_INTEGER:
157 case CTF_TYPE_FLOAT:
158 case CTF_TYPE_STRING:
159 case CTF_TYPE_ENUM:
160 goto error;
161 case CTF_TYPE_STRUCT:
162 {
163 struct definition_struct *def_struct;
164
165 def_struct = container_of(scope, struct definition_struct, p);
166 if (!def_struct)
167 goto error;
168 if (def_struct->fields->pdata) {
169 *list = (struct definition const* const*) def_struct->fields->pdata;
170 *count = def_struct->fields->len;
171 goto end;
172 } else {
173 goto error;
174 }
175 }
176 case CTF_TYPE_UNTAGGED_VARIANT:
177 goto error;
178 case CTF_TYPE_VARIANT:
179 {
180 struct definition_variant *def_variant;
181
182 def_variant = container_of(scope, struct definition_variant, p);
183 if (!def_variant)
184 goto error;
185 if (def_variant->fields->pdata) {
186 *list = (struct definition const* const*) def_variant->fields->pdata;
187 *count = def_variant->fields->len;
188 goto end;
189 } else {
190 goto error;
191 }
192 }
193 case CTF_TYPE_ARRAY:
194 {
195 struct definition_array *def_array;
196
197 def_array = container_of(scope, struct definition_array, p);
198 if (!def_array)
199 goto error;
200 if (def_array->elems->pdata) {
201 *list = (struct definition const* const*) def_array->elems->pdata;
202 *count = def_array->elems->len;
203 goto end;
204 } else {
205 goto error;
206 }
207 }
208 case CTF_TYPE_SEQUENCE:
209 {
210 struct definition_sequence *def_sequence;
211
212 def_sequence = container_of(scope, struct definition_sequence, p);
213 if (!def_sequence)
214 goto error;
215 if (def_sequence->elems->pdata) {
216 *list = (struct definition const* const*) def_sequence->elems->pdata;
217 *count = def_sequence->elems->len;
218 goto end;
219 } else {
220 goto error;
221 }
222 }
223 default:
224 break;
225 }
226
227end:
228 return 0;
229
230error:
231 *list = NULL;
232 *count = 0;
233 return -1;
234}
235
236uint64_t bt_ctf_get_timestamp(struct bt_ctf_event *event)
237{
238 if (event && event->stream->has_timestamp)
239 return event->stream->timestamp;
240 else
241 return 0;
242}
243
244static void bt_ctf_field_set_error(int error)
245{
246 bt_ctf_last_field_error = error;
247}
248
249int bt_ctf_field_get_error(void)
250{
251 int ret;
252 ret = bt_ctf_last_field_error;
253 bt_ctf_last_field_error = 0;
254
255 return ret;
256}
257
258uint64_t bt_ctf_get_uint64(struct definition *field)
259{
260 unsigned int ret = 0;
261
262 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
263 ret = get_unsigned_int(field);
264 else
265 bt_ctf_field_set_error(-EINVAL);
266
267 return ret;
268}
269
270int64_t bt_ctf_get_signed_int64(struct definition *field)
271{
272 int ret = 0;
273
274 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
275 ret = get_signed_int(field);
276 else
277 bt_ctf_field_set_error(-EINVAL);
278
279 return ret;
280
281}
282
283char *bt_ctf_get_char_array(struct definition *field)
284{
285 char *ret = NULL;
286
287 if (field && bt_ctf_field_type(field) == CTF_TYPE_ARRAY)
288 ret = get_char_array(field)->str;
289 else
290 bt_ctf_field_set_error(-EINVAL);
291
292 return ret;
293}
294
295char *bt_ctf_get_string(struct definition *field)
296{
297 char *ret = NULL;
298
299 if (field && bt_ctf_field_type(field) == CTF_TYPE_STRING)
300 ret = get_string(field);
301 else
302 bt_ctf_field_set_error(-EINVAL);
303
304 return ret;
305}
This page took 0.032311 seconds and 4 git commands to generate.